home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume16 / nethck31 / part76 < prev    next >
Encoding:
Internet Message Format  |  1993-02-05  |  57.2 KB

  1. Path: uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v16i084:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part76/108
  5. Message-ID: <4447@master.CNA.TEK.COM>
  6. Date: 5 Feb 93 19:20:03 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 1433
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1635
  11.  
  12. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  13. Posting-number: Volume 16, Issue 84
  14. Archive-name: nethack31/Part76
  15. Supersedes: nethack3p9: Volume 10, Issue 46-102
  16. Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
  17.  
  18.  
  19.  
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then unpack
  22. # it by saving it into a file and typing "sh file".  To overwrite existing
  23. # files, type "sh file -c".  You can also feed this as standard input via
  24. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  25. # will see the following message at the end:
  26. #        "End of archive 76 (of 108)."
  27. # Contents:  sys/vms/Install.vms win/X11/winstat.c
  28. # Wrapped by billr@saab on Wed Jan 27 16:09:17 1993
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'sys/vms/Install.vms' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'sys/vms/Install.vms'\"
  32. else
  33. echo shar: Extracting \"'sys/vms/Install.vms'\" \(29376 characters\)
  34. sed "s/^X//" >'sys/vms/Install.vms' <<'END_OF_FILE'
  35. X               Instructions for Installing NetHack 3.1.0
  36. X                           on a VMS system
  37. X               =========================================
  38. X
  39. X0.  Please read this entire file before trying to build or install
  40. X    NetHack, then read it again!
  41. X
  42. X1.  Building NetHack requires a C compiler (either VAX C, DEC C, or GNU C)
  43. X    and VMS version V4.6 or later (but see note #11).  This release has
  44. X    been tested on VAX/VMS V5.5-2, T6.0, and Alpha/VMS V1.0.  The build
  45. X    procedure (vmsbuild.com) should not need to be modified; it accepts
  46. X    an option for selecting VAXC vs GNUC, and it can detect different
  47. X    versions of VAXC to use appropriate CC command qualifiers.  Versions
  48. X    of VAXC earlier than V2.3 will produce many warning messages (about
  49. X    150 per source file; over to 18,000 total!), but NetHack has been
  50. X    verified to compile, link, and execute correctly when built with VAXC
  51. X    V2.2 using vmsbuild.com.  There is also a set of Makefiles suitable
  52. X    for use with MMS; they may or may not work with other make utilities.
  53. X
  54. X2.  Make sure all the NetHack files are in the appropriate directory
  55. X    structure.  You should set up a directory--referred to as "top" below
  56. X    and in some of the assorted files, but which may be a subdirectory--
  57. X    that has these subdirectories
  58. X        [.dat]          -- data files
  59. X        [.doc]          -- documentation files
  60. X        [.include]      -- C header files
  61. X        [.src]          -- primary source files
  62. X        [.sys]          -- parent for [.sys.*]
  63. X        [.sys   .share] -- files shared by several ports, incl. VMS
  64. X        [.sys   .vms]   -- VMS-specific source and support files
  65. X        [.util]         -- sources for essential utility programs
  66. X        [.win]          -- parent for [.win.*]
  67. X        [.win   .tty]   -- "window" routines for ordinary terminals
  68. X                           (including terminal windows on workstations)
  69. X    The following subdirectories may be present, but are not useful for
  70. X    building NetHack on VMS and are not required:
  71. X        [.sys   .amiga] -- AmigaDOS
  72. X        [.sys   .amiga   .splitter]
  73. X        [.sys   .atari] -- Atari TOS
  74. X        [.sys   .mac]   -- Macintosh
  75. X        [.sys   .msdos] -- MSDOS for IBM PCs and compatibles
  76. X        [.sys   .os2]   -- OS/2
  77. X        [.sys   .unix]  -- guess :-)
  78. X        [.win   .X11]   -- window routines for X-Windows; requires X11R4
  79. X                           or later and MIT's Athena Widget set
  80. X    You must arrange things in this structure or the supplied procedures
  81. X    and instructions in this file will not work properly.  Several DCL
  82. X    command files are present in the [.sys.vms] subdirectory and won't
  83. X    work as intended if they're moved elsewhere.  The file called Files
  84. X    in the top directory contains lists of everything that should be in
  85. X    each subdirectory, including things that are constructed as NetHack
  86. X    is being built.  If you obtain the NetHack distribution via the
  87. X    "shar" packaging used for Usenet newsgroup comp.sources.games and its
  88. X    archives, you may have to reconstruct several files that were split
  89. X    for posting.  At the time of this writing, the list of files needing
  90. X    such treatment is not known, so they can't be enumerated here or
  91. X    handled automatically be the build procedures.
  92. X
  93. X3.  Prior to beginning compilation, go to the [.include] subdirectory and
  94. X    edit vmsconf.h according to its comments.  You should set Local_WIZARD
  95. X    and Local_HACKDIR to appropriate values, and you might want to define
  96. X    TEXTCOLOR if you have any color VAXstations or color terminals which
  97. X    handle ANSI-format escape sequences to set foreground and background
  98. X    color for text characters.  (VT241/VT340 color graphics won't work.)
  99. X    Other things which may be of interest are SECURE if you intend to
  100. X    set up NetHack as an installed image which is granted privileges, and
  101. X    SHELL which should be disabled if you intend to allow captive accounts
  102. X    to run NetHack.  You may also want to edit file config.h, but that's
  103. X    only necessary if you want or need to disable some of the game options.
  104. X    The distributed copy of config.h will work successfully on VMS;
  105. X    vmsconf.h has conditional code to deal with the UNIX-specific items.
  106. X
  107. X4.  If you have the programming utilities lex or flex and yacc or bison,
  108. X    you may edit the procedure [.sys.vms]spec_lev.com and execute it to
  109. X    process several source files for NetHack's special level and dungeon
  110. X    compilers.  If you don't modify spec_lev.com, it will copy some
  111. X    pre-processed versions of the appropriate files (dgn_lex.c, lev_lex.c,
  112. X    dgn_yacc.c, lev_yacc.c, dgn_comp.h, and lev_comp.h) from [.sys.share]
  113. X    into [.util]*.c and [.include]*.h.
  114. X       $ @[.SYS.VMS]SPEC_LEV            ![OPTIONAL]
  115. X    If you perform this step, do it prior to executing vmsbuild.com; if
  116. X    you don't perform this step, vmsbuild.com will do so for you.
  117. X
  118. X5.  If you are using DEC C (not to be confused with Digital's VAX C) as
  119. X    your compiler, you should create an empty file called CRTL.OPT in the
  120. X    [.src] subdirectory.  This is a linker options file for accessing
  121. X    the C run-time library.  If you don't create it, vmsbuild.com will
  122. X    construct one suitable for linking with shareable VAXCRTL.  Programs
  123. X    compiled with DEC C should link with DECC$SHR instead; no special
  124. X    linker options are needed in that case and VAXCRTL should be avoided.
  125. X    You should also create a DCL symbol for invoking CC that specifies
  126. X    VAXC compatibility mode.
  127. X       $ CC == "CC/Standard=VAXC"
  128. X    You might also want to specify /noOptimize if you don't trust the V1
  129. X    compiler's optimizer yet.  No other special qualifiers are needed.
  130. X
  131. X6.  To build NETHACK.EXE and its auxiliary programs, execute the
  132. X    following DCL command:
  133. X       $ @[.SYS.VMS]VMSBUILD    !defaults to VAXC unless symbol 'CC' exists
  134. X    or $ @[.SYS.VMS]VMSBUILD "GNUC"
  135. X    It can take quite a bit of time for a full build to complete.
  136. X    vmsbuild.com will display some feedback as it executes; generally
  137. X    this will be the name of each source file that's about to be compiled
  138. X    or the name of the executable that has just been linked.
  139. X
  140. X7.  After compilation, it's time to perform installation.  Go back to
  141. X    the top directory.  Either edit [.sys.vms]install.com to indicate
  142. X    where you want everything to be installed, or specify the location
  143. X    and "playground" owner on the command line.  Then execute either
  144. X       $ @[.SYS.VMS]INSTALL
  145. X    or $ @[.SYS.VMS]INSTALL location owner
  146. X    where location is a device:[directory] specification and owner is
  147. X    either a rights identifier or UIC.  If install.com is not modified
  148. X    and if values aren't supplied on the command line, the default values
  149. X    used are the translation of logical name HACKDIR, if any, or else
  150. X    [.PLAY] (relative to the current directory), and the UIC for the
  151. X    current process.  install.com will use the auxiliary programs
  152. X    constructed by vmsbuild.com to process quite a few data files in the
  153. X    [.dat] subdirectory.  Then it will create the playground directory,
  154. X    if necessary, plus the associated [.save] subdirectory.  Next it will
  155. X    copy the data files into the playground; this step can take a while.
  156. X    Finally it will copy nethack.exe and a few additional support files.
  157. X
  158. X    After it completes, the files [.src]nethack.olb, [.src]nethack.exe,
  159. X    [.util]*.obj, [.util]*_comp.exe, and [.util]makedefs.exe can be
  160. X    deleted in order to save disk space if desired.  The other program,
  161. X    [.util]recover.exe, should not be deleted unless you make a copy of
  162. X    it somewhere--perhaps in the playground directory--first.  It can be
  163. X    used to resurrect some games disrupted by system or program crash.
  164. X
  165. X8.  The file nethack.com which is copied to the playground directory can
  166. X    be used to invoke NetHack, or nethack.exe can be run directly.  Most
  167. X    of the command-line options specified in the Unix man-page (file
  168. X    [.dat]nethack.6) are also applicable to VMS.  Some comments at the
  169. X    beginning of nethack.com illustrate several of the options.  New
  170. X    players should read the document file "Guidebook.txt" which will
  171. X    be available in the playground directory.
  172. X
  173. X
  174. XNotes:
  175. X
  176. X1.  Save files and bones files from previous versions will not work with
  177. X    NetHack 3.1.0.  Don't bother trying to keep them.  Ditto for RECORD,
  178. X    the scoreboard file.  One minor change of note is that the default
  179. X    name for a player's character is now a lowercase copy of the username.
  180. X
  181. X2.  To specify user-preference options in your environment, define the
  182. X    logical name NETHACKOPTIONS to have value of a quoted string
  183. X    containing a comma separated list of option values.  The option names
  184. X    are case-insensitive.
  185. X       $ define nethackoptions "noPickup,Dog:Rover,Cat:Felix,DECgraphics"
  186. X    One value you'll probably want to specify is "noLegacy" to turn off
  187. X    the initial introductory passage.  The "checkpoint" option controls
  188. X    whether or not enough data is saved to disk so that the set of level
  189. X    files left behind after a crash contains sufficient information for
  190. X    recover.exe to be able to construct a save file after the fact.  The
  191. X    tradeoff for enabling checkpoint is that using it makes level changes
  192. X    do more I/O and take longer.
  193. X
  194. X    If logical name or DCL symbol NETHACKOPTIONS is not defined, NetHack
  195. X    will try HACKOPTIONS instead.  Regardless of whether or not either
  196. X    is defined, it will also try to find a configuration file containing
  197. X    additional option settings.  If the value of the translation of
  198. X    NETHACKOPTIONS--or HACKOPTIONS--begins with an "@" character then the
  199. X    rest of the translation is assumed to be the name of the configuration
  200. X    file.  Otherwise, the following are tried:  file specified by logical
  201. X    name NETHACKINI, file SYS$LOGIN:NETHACK.INI, and file HOME:NETHACK.CNF
  202. X    (note that the C run-time library sets up the value of HOME to match
  203. X    sys$login).  Syntax for the configuration file is essentially the same
  204. X    as for NETHACKOPTIONS, but multiple lines can be used and comments can
  205. X    be included by placing '#' in the first column.
  206. X
  207. X3.  Instead of using vmsbuild.com to compile and link everything, you can
  208. X    use the set of Makefiles found in the vms subdirectory, provided you
  209. X    have an appropriate and compatible make utility.  They've been tested
  210. X    using Digital's MMS.  There are five of them, and the suffix or
  211. X    filetype on their names indicates where they should be placed.
  212. X       $ copy [.sys.vms]Makefile.top []Makefile.
  213. X       $ copy [.sys.vms]Makefile.src [.src]Makefile.
  214. X       $ copy [.sys.vms]Makefile.utl [.util]Makefile.
  215. X       $ copy [.sys.vms]Makefile.dat [.dat]Makefile.
  216. X       $ copy [.sys.vms]Makefile.doc [.doc]Makefile.
  217. X    After doing that, edit [.src]Makefile and [.util]Makefile to specify
  218. X    pertinent compiler options in CFLAGS, linker options in LFLAGS, and
  219. X    libraries in LIBS and/or MORELIBS if the default values aren't right.
  220. X    Be sure to make compatible compilation and linking settings in both
  221. X    files.  While in there, edit [.util]Makefile to specify the appropriate
  222. X    values for lex and yacc, _or_ move to that directory and use MMS or
  223. X    make to build targets no_lex and no_yacc which will copy several
  224. X    pre-processed files from [.sys.share] into [.util].  Finally, edit
  225. X    Makefile in the top directory to specify values for GAMEDIR and
  226. X    GAMEOWNER.  This top Makefile invokes [.sys.vms]install.com to do
  227. X    much of the actual installation work, so if you want to make any
  228. X    customizations or file protection changes, edit install.com to suit.
  229. X    Also set MAKE in all of the Makefiles to the appropriate command if
  230. X    not using MMS.
  231. X
  232. X    Once the Makefiles are tailored for your site, give the command
  233. X       $ mms all,install
  234. X    or $ make all install
  235. X    To compile and install everything.  The object files compiled via
  236. X    the Makefiles are left as individual .OBJ files rather than placed
  237. X    into an object library (in contrast to step #7 above and note #12
  238. X    below).  These Makefiles are provided on an as-is basis; vmsbuild.com
  239. X    is the preferred way to compile because it's guaranteed to compile
  240. X    and link everything.
  241. X
  242. X4.  VMS NetHack uses the termcap routines borrowed from GNU Emacs.  These
  243. X    have been supplied for those who do not already have GNU Emacs, but
  244. X    they are not properly a part of the NetHack distribution.  Since
  245. X    these files (gnutermcap.c and gnutparam.c) bear the usual GNU license,
  246. X    any executable made with these files is also under the GNU license,
  247. X    which among other things means you must be prepared to distribute
  248. X    all the source that went into the executable if you distribute the
  249. X    executable.  See the GNU license in the files for further details.
  250. X    Since NetHack itself has a very similar license, this should not be
  251. X    an issue.
  252. X
  253. X5.  termcap is an ASCII data file containing descriptions of terminal
  254. X    capabilities and the escape sequences that software must use to take
  255. X    advantage of them.  If you do not already have a termcap file in use
  256. X    on your system there is a small one in file [.SYS.SHARE]TERMCAP.  It
  257. X    contains definitions for common Digital terminals, also suitable for
  258. X    most clones and emulators.  This file is copied into the playground
  259. X    by install.com, and NetHack will use it if it can't find any other
  260. X    one.  NetHack uses the following sequence to attempt to locate the
  261. X    termcap file:  translation of the logical name TERMCAP (used as-is),
  262. X    file NETHACKDIR:TERMCAP, similar file HACKDIR:TERMCAP, GNU-Emacs file
  263. X    EMACS_LIBRARY:[ETC]TERMCAP.DAT, file []TERMCAP, and lastly file
  264. X    $TERMCAP (which most likely would be a logical name).  If NetHack
  265. X    can't find the termcap file, or if the above search sequence finds a
  266. X    different one than you'd prefer, then use the DCL ASSIGN or DEFINE
  267. X    command to define a value for logical name TERMCAP.
  268. X
  269. X    NetHack also tries fairly hard to figure out what kind of terminal
  270. X    you're using.  It checks for logical names (or symbols) NETHACK_TERM,
  271. X    HACK_TERM, EMACS_TERM, and lastly TERM.  The last is set up by the
  272. X    C run-time library and you cannot use a logical name or symbol for
  273. X    it.  If all those fail, or if whichever one succeeds has a value of
  274. X    "undefined" or "unknown" (which can happen under VMS V5.4-* and
  275. X    V5.5-* for VT420 terminals), NetHack will query the VMS TERMTABLE
  276. X    database used by the SMG library routines.  Whatever value NetHack
  277. X    eventually comes up with needs to be the name of an entry in the
  278. X    termcap file, otherwise a message about "Unknown terminal type" will
  279. X    be printed and NetHack will exit.
  280. X
  281. X6.  If you want to use GEM C for cross-compiling from VAX/VMS to Alpha/VMS
  282. X    or vice versa, you'll have to build in stages.  For the first pass,
  283. X    use a value of CC appropriate for the host system, interactively
  284. X    start vmsbuild.com as described in step #6 above, wait until it has
  285. X    compiled and linked "makedefs", then use <ctrl/C> to interrupt it
  286. X    (after the "12:34 makedefs" feedback message) so that it doesn't
  287. X    waste any time compiling the rest of the code.  Consider that to be
  288. X    stage 1.  For stage 2, go back to step #5, but set the symbol for
  289. X    invoking CC to have a value similar to the following
  290. X       $ CC == " GEMC/Standard=VAXC"
  291. X    Note the leading space in the value; if that's not included, vmsbuild
  292. X    will take the leading "G" as an indication that GCC is being used and
  293. X    end up selecting some wrong options.  Also set up symbols for cross-
  294. X    architecture access to the linker and librarian (these examples assume
  295. X    building an AXP version from a VAX)
  296. X       $ LINK == "LINK/Alpha"   !or LINK/VAX
  297. X       $ LIBR == "LIBR/Alpha"   !or LIBR/VAX
  298. X    Now re-do step #6, but specify "/noExe" as the 4th parameter to
  299. X    vmsbuild.com.
  300. X       $ @[.SYS.VMS]VMSBUILD "" "" "" "/noExe"
  301. X    Note the three empty strings used as placeholders.  That's the end of
  302. X    stage 2; everything will be compiled to object files but no executable
  303. X    files will have been linked.  If you don't do things this way, a new
  304. X    version of makedefs will be linked; but since it will be appropriate
  305. X    for the target, vmsbuild's attempt to use it on the host will fail.
  306. X    For stage 3, link nethack.exe using vmsbuild.com
  307. X       $ @[.SYS.VMS]VMSBUILD "LINK"
  308. X    Don't specify "/noExe" this time around or you'll just be wasting
  309. X    your time and CPU cycles. ;-)  For stage 4, link all four of the
  310. X    utility programs manually (there's no vmsbuild option for this).
  311. X    Go to the [.util] subdirectory and issue these commands
  312. X       $ LINK makedefs,[-.src]nethack/Lib
  313. X       $ LINK/Exe=[]lev_comp lev_main,lev_yacc,lev_lex,panic,[-.src]nethack/Lib
  314. X       $ LINK/Exe=[]dgn_comp dgn_main,dgn_yacc,dgn_lex,panic,[-.src]nethack/Lib
  315. X       $ LINK recover,[-.src]nethack/Lib
  316. X    Note that these commands are slightly simpler than the corresponding
  317. X    ones used in vmsbuild.com; crtl.opt is expected to be empty (step #5
  318. X    above) so omitted here, and the identification directive is optional.
  319. X
  320. X    The installation of the playground (step #7 above) must be done on
  321. X    the target system but should need no special cross-architecture
  322. X    contortions.
  323. X
  324. X7.  NetHack contains code which attempts to make it secure in case it's
  325. X    installed with privileges (to allow the playground to be protected
  326. X    against world write access).  This has only undergone limited testing,
  327. X    so install NetHack with privileges at your own risk.  If you discover
  328. X    any potential security holes, please let us know so that we can take
  329. X    steps to correct the problem(s).  NetHack always includes filename
  330. X    punctuation when accessing files, so that it should never be affected
  331. X    by inadvertent or malicious logical name definitions, and it always
  332. X    deactivates installed privileges prior to spawning a subprocess.
  333. X
  334. X    Note to end users:  "installing with privileges" is an option for
  335. X    system managers who set up system-wide access to the game.  Since
  336. X    CMKRNL privilege and modification of the system boot routines are
  337. X    both required, it is not an option for ordinary users.  There are
  338. X    no explicit instructions on how to do such an installation, because
  339. X    only system managers who are already familiar with the process and
  340. X    its potential security ramifications should even consider it.
  341. X
  342. X    The default setup by install.com assumes no privileges and uses
  343. X    world-writeable files to allow arbitrary users to play.  This is
  344. X    NOT secure and not advisable in any environment where there are
  345. X    untrustworthy users, but works fine for many sites.  If you allow
  346. X    users to run NetHack from captive accounts (VMS 5.1-* or earlier)
  347. X    or from restricted accounts (5.2 and later), you should either make
  348. X    sure that they do not have TMPMBX privilege or else disable NetHack's
  349. X    ability to spawn an interactive subprocess.  To disable subprocesses,
  350. X    disable the "!" (shell escape) command by commenting out the definition
  351. X    of SHELL in vmsconf.h prior to building the program.  This necessity
  352. X    may be removed in some future release, where NetHack will check for
  353. X    captive accounts instead of spawning unconditionally.  Note that
  354. X    disabling the SHELL command also prevents spawning MAIL when scrolls
  355. X    of new mail are received.
  356. X
  357. X    In order for installed privileges to be used at all, the value of
  358. X    HACKDIR (via Local_HACKDIR in vmsconf.h) compiled into the program
  359. X    must correspond to the actual playground directory.  If logical name
  360. X    HACKDIR (or NETHACKDIR) is used to override that value, installed
  361. X    privileges will be deactivated unless its value corresponds to the
  362. X    same device and directory as the internal value.  If that internal
  363. X    value contains a logical name, only an executive-mode translation
  364. X    will be honored; if there is no such translation, installed privs
  365. X    will be deactivated.
  366. X
  367. X    To be able to install nethack.exe with privileges (SYSPRV or GRPPRV,
  368. X    perhaps EXQUOTA, depending on site usage and needs), you'll need to
  369. X    link it with debugging and tracebacks both disabled.  You can do this
  370. X    by specifying an argument to vmsbuild.com when performing step #6
  371. X    above; pass it "/noTrace/noDebug" as the 4th parameter.
  372. X       $ @[.SYS.VMS]VMSBUILD "" "" "" "/noTrace/noDebug"
  373. X    /Trace/noDebug is the linker's normal default.  If you've already
  374. X    built NetHack, you can relink with tracebacks disabled by doing
  375. X       $ @[.SYS.VMS]VMSBUILD "LINK" "" "" "/noTrace/noDebug"
  376. X
  377. X8.  If you can't or won't install nethack.exe with privileges and if you
  378. X    don't have access to a privileged account yourself, then if you intend
  379. X    to allow other users to access your copy of NetHack you should probably
  380. X    place an ACL on the playground directory and its save subdirectory.
  381. X    The access control list should contain a default protection ACE which
  382. X    grants delete+control access to the playground owner (ie, your own
  383. X    account if there's no special games account involved).  install.com
  384. X    does not attempt to do this automatically at the present time.  After
  385. X    executing install.com to create the playground directory, perform a
  386. X    pair of commands similar to the following
  387. X       $ SET ACL/ACL=(IDENT=your_id, OPTIONS=DEFAULT, ACCESS=R+W+E+D+C) -
  388. X       $_ device:[playground's.parent.directory]playground.DIR
  389. X       $ SET ACL/ACL=(IDENT=your_id, OPTIONS=DEFAULT, ACCESS=R+W+E+D+C) -
  390. X       $_ device:[playground.directory]SAVE.DIR
  391. X    The two commands use the same options, but SET ACL won't accept a
  392. X    list of files to modify.  'your_id' should be the rights identifier
  393. X    which corresponds to the account which should retain access to those
  394. X    files; 'device:[playground's.parent.directory]' is the name of the
  395. X    parent directory for the playground (ie, if your playground directory
  396. X    is disk$foo:[me.games.nethack.play], then you want to specify
  397. X    disk$foo:[me.games.nethack]play.dir on the SET ACL command), and
  398. X    'device:[playground.directory]' is the playground itself.  Those ACLs
  399. X    establish a default protection scheme such that every newly created
  400. X    file in those directories will have an ACL attached to it, and the
  401. X    attached ACL will grant 'your_id' full access to the corresponding
  402. X    file.  That should allow you to clear away level files from aborted
  403. X    games, and to delete old save files if necessary.  It will not enable
  404. X    you to run recover.exe on behalf of other users, because you won't be
  405. X    able to create files owned by them unless you have elevated privileges.
  406. X
  407. X9.  Many NetHack commands can be aborted by sending it the <escape>
  408. X    character when it wants input.  This is displayed as ESC inside the
  409. X    game.  Digital VK201 keyboards (used by VT2xx and VT3xx and older
  410. X    VAXstations) and VK401 keyboards (used by VT4xx, newer VAXstations,
  411. X    and DEC's X Terminals) do not have an <escape> key.  They may
  412. X    transmit <escape> for the <F11> key if the terminal or emulator
  413. X    window is set to operate in VT100 mode, or there may be a setup-type
  414. X    option for making the <` | ~> key behave as <escape>.  If your
  415. X    terminal does not have that, or if it's set to a mode where that
  416. X    won't work, then just use <ctrl/[> instead.  (Press the "[" key while
  417. X    holding down the "Ctrl" key, then release both; <escape> and <ctrl/[>
  418. X    have the same ASCII code and are indistinguishable once they reach
  419. X    the computer; note that VAXstations and X Terminals _can_ tell the
  420. X    difference, but that won't matter for NetHack.)
  421. X
  422. X    VMS NetHack is configured to use the SYS$QIOW system service for
  423. X    reading characters from the keyboard.  This allows ^C and ^Y (as well
  424. X    as ^X and ^O for wizard mode debugging) to be used as commands without
  425. X    being intercepted or interpreted by the terminal driver.  The code
  426. X    which parses arrow and function keys is not perfect, and it's possible
  427. X    to get strange results if you hold such keys down to just type too
  428. X    quickly, particularly on slow multiplexor lines.  Those keys are
  429. X    never needed in actual play, and most function keys are just treated
  430. X    as <escape> for use in aborting partial commands.
  431. X
  432. X    VMS NetHack also still has code to use SMG$READ_KEYSTROKE instead.
  433. X    That can be activated by modifying vmsconf.h and recompiling, but
  434. X    it should never be necessary.  If you use it, you'll need to press
  435. X    either <esc> or <ctrl/[> twice to abort partial commands, or else
  436. X    press an arbitrary function key, such as <PF4>, once.
  437. X
  438. X    If SUSPEND is defined in vmsconf.h, <ctrl/Z> is used for that command.
  439. X    Since Unix-style job control is not available, it's used for connecting
  440. X    to the parent process if NetHack is running in a subprocess.  When not
  441. X    in a subprocess, it doesn't do anything except give a message to the
  442. X    effect that it's not doing anything....  The suspend command does not
  443. X    save the current game; if you use ^Z to attach to your parent process,
  444. X    be sure to remember to eventually reattach to the NetHack subprocess;
  445. X    otherwise the game in progress won't get saved when you logout.
  446. X
  447. X10. NetHack optionally maintains a logfile which receives one line appended
  448. X    to it whenever a game ends.  This can be disabled entirely by adding
  449. X    an "#undef LOGFILE" directive to vmsconf.h prior to building the
  450. X    program, or it can be disabled later by removing the file(s) LOGFILE.;*
  451. X    from the playground directory.  If not disabled prior to compilation,
  452. X    the logfile can be reinitialized by simply creating an empty file
  453. X    named LOGFILE in the playground, but make sure that users are able
  454. X    to write into it, or new entries will not be appended.
  455. X
  456. X11. Some attempt at support for VMS versions earlier than V4.6 has been
  457. X    included, but no such obsolete system was available for testing it.
  458. X    vmsbuild.com detects the need for the extra support routines and
  459. X    arranges automatically for them to be compiled.  The reason that
  460. X    special support is needed is that the C Run-Time Library (VAXCRTL)
  461. X    underwent a major revision for VMS V4.6 and several routines which
  462. X    NetHack utilizes were not available prior to that upgrade.
  463. X
  464. X12. vmsbuild.com collects almost all of the object files (xxx.OBJ) into
  465. X    an object library (NETHACK.OLB) as it compiles the source files.
  466. X    This should prevent the quota-exceeded problems from the linker
  467. X    that some sites have reported for prior versions.  Note that if you
  468. X    compile any source files manually, you'll need to replace those
  469. X    modules in the object library prior to linking the program:
  470. X       $ cc/include=[-.include] [-.sys.vms]vmstty   !for example
  471. X       $ libr/obj []nethack vmstty                  !replace VMSTTY
  472. X       $ @[-.sys.vms]vmsbuild LINK                  !re-link NETHACK.EXE
  473. X    If you forget to replace the library entry, your newly compiled code
  474. X    will not be included in the new executable image.
  475. X
  476. X13. To access "wizard mode"--intended for debugging purposes, not to
  477. X    spoil the game with unlimited wishes--you must be running from the
  478. X    username compiled into the game via Local_WIZARD in vmsconf.h, and
  479. X    you must specify "-D" on the command line when invoking NetHack.
  480. X    Note that it must be uppercase, and it must be in quotes to prevent
  481. X    the C run-time library's program startup code from converting it into
  482. X    lowercase.  Any character name will be ignored in favor of "wizard".
  483. X
  484. X14. Unless you have both Motif and the Athena Widget set from MIT, you
  485. X    will not be able to use the X11 interface on VMS.  Even if you do
  486. X    have both those things, such a configuration has not been tested and
  487. X    there are no provisions for it in vmsbuild.com.  Makefile.src does
  488. X    have the extra source files listed, but not the necessary libraries.
  489. X
  490. X    The X11 port will not compile and link with DECwindows, but it will
  491. X    be able to display on a VMS DECwindows X server provided that it and
  492. X    its Unix X client have a compatible transport between them (either
  493. X    TCP/IP added to VMS or DECnet added to Unix) and session security
  494. X    is set up appropriately.  You'll need to add the contents of file
  495. X    [.win.X11]NetHack.ad into your DECW$USER_DEFAULTS:DECW$XDEFAULTS.DAT,
  496. X    and modify some of the lines.  The DECwindows window manager does not
  497. X    support having input focus automatically follow the pointer, so you
  498. X    should uncomment the "NetHack*autofocus" resource line.  (For Motif
  499. X    this may not be necessary, depending on customization options.)
  500. X    Uncommenting the "NetHack*slow" line is highly recommended.  You'll
  501. X    also need to set "NetHack*fonts: fixed" (rather than "variable"), and
  502. X    either set the map font to "fixed" too or install the "nh10" font
  503. X    that comes in file [.win.X11]nh10.bdf.  If NetHack warns that the map
  504. X    font is variable, then something isn't set up properly.
  505. X
  506. X    After creating or modifying decw$xdefaults.dat, you must restart the
  507. X    window manager in order for any changes to take effect; it's easiest
  508. X    to just make the session manager quit and then log in again.
  509. X
  510. X15. There is no support for VMS POSIX in this release of NetHack.
  511. X
  512. X16. If necessary, send problem reports via e-mail to
  513. X       "nethack-bugs@linc.cis.upenn.edu"  (numeric address 130.91.6.8).
  514. X    Always include version information for NetHack, the operating system,
  515. X    and the C compiler used.
  516. X
  517. X23-JAN-1993
  518. END_OF_FILE
  519. if test 29376 -ne `wc -c <'sys/vms/Install.vms'`; then
  520.     echo shar: \"'sys/vms/Install.vms'\" unpacked with wrong size!
  521. fi
  522. # end of 'sys/vms/Install.vms'
  523. fi
  524. if test -f 'win/X11/winstat.c' -a "${1}" != "-c" ; then 
  525.   echo shar: Will not clobber existing file \"'win/X11/winstat.c'\"
  526. else
  527. echo shar: Extracting \"'win/X11/winstat.c'\" \(25001 characters\)
  528. sed "s/^X//" >'win/X11/winstat.c' <<'END_OF_FILE'
  529. X/*    SCCS Id: @(#)winstat.c    3.1    92/3/7
  530. X/* Copyright (c) Dean Luick, 1992                  */
  531. X/* NetHack may be freely redistributed.  See license for details. */
  532. X
  533. X/*
  534. X * Status window routines.  This file supports both the "traditional"
  535. X * tty status display and a "fancy" status display.  A tty status is
  536. X * made if a popup window is requested, otherewise a fancy status is
  537. X * made.  This code assumes that only one fancy status will ever be made.
  538. X * Currently, only one status window (of any type) is _ever_ made.
  539. X */
  540. X#include <X11/Intrinsic.h>
  541. X#include <X11/StringDefs.h>
  542. X#include <X11/Shell.h>
  543. X#include <X11/Xaw/AsciiText.h>
  544. X#include <X11/Xaw/Cardinals.h>
  545. X#include <X11/Xaw/Form.h>
  546. X#include <X11/Xaw/Label.h>
  547. X
  548. X#include "hack.h"
  549. X#include "winX.h"
  550. X
  551. Xextern const char *hu_stat[]; /* from eat.c */
  552. Xextern const char *enc_stat[]; /* from botl.c */
  553. X
  554. Xstatic void update_fancy_status();
  555. Xstatic Widget create_fancy_status();
  556. X
  557. Xvoid
  558. Xcreate_status_window(wp, create_popup, parent)
  559. X    struct xwindow *wp;            /* window pointer */
  560. X    boolean create_popup;
  561. X    Widget parent;
  562. X{
  563. X    XFontStruct *fs;
  564. X    Arg args[8];
  565. X    Cardinal num_args;
  566. X    Position top_margin, bottom_margin, left_margin, right_margin;
  567. X
  568. X    wp->type = NHW_STATUS;
  569. X
  570. X    if (!create_popup) {
  571. X    /*
  572. X     * If we are not creating a popup, then we must be the "main" status
  573. X     * window.
  574. X     */
  575. X    if (!parent)
  576. X        panic("create_status_window: no parent for fancy status");
  577. X    wp->status_information = 0;
  578. X    wp->w = create_fancy_status(parent, (Widget) 0);
  579. X    return;
  580. X    }
  581. X
  582. X    wp->status_information =
  583. X        (struct status_info_t *) alloc(sizeof(struct status_info_t));
  584. X
  585. X    init_text_buffer(&wp->status_information->text);
  586. X
  587. X    num_args = 0;
  588. X    XtSetArg(args[num_args], XtNallowShellResize, False); num_args++;
  589. X    XtSetArg(args[num_args], XtNinput, False);            num_args++;
  590. X
  591. X    wp->popup = parent = XtCreatePopupShell("status_popup",
  592. X                    topLevelShellWidgetClass,
  593. X                    toplevel, args, num_args);
  594. X
  595. X    num_args = 0;
  596. X    XtSetArg(args[num_args], XtNdisplayCaret, False); num_args++;
  597. X    XtSetArg(args[num_args], XtNscrollHorizontal,
  598. X                    XawtextScrollWhenNeeded);    num_args++;
  599. X    XtSetArg(args[num_args], XtNscrollVertical,
  600. X                    XawtextScrollWhenNeeded);    num_args++;
  601. X
  602. X    wp->w = XtCreateManagedWidget(
  603. X        "status",        /* name */
  604. X        asciiTextWidgetClass,
  605. X        parent,            /* parent widget */
  606. X        args,            /* set some values */
  607. X        num_args);        /* number of values to set */
  608. X
  609. X    /*
  610. X     * Adjust the height and width of the message window so that it
  611. X     * is two lines high and COLNO of the widest characters wide.
  612. X     */
  613. X
  614. X    /* Get the font and margin information. */
  615. X    num_args = 0;
  616. X    XtSetArg(args[num_args], XtNfont,          &fs);           num_args++;
  617. X    XtSetArg(args[num_args], XtNtopMargin,    &top_margin);    num_args++;
  618. X    XtSetArg(args[num_args], XtNbottomMargin, &bottom_margin); num_args++;
  619. X    XtSetArg(args[num_args], XtNleftMargin,   &left_margin);   num_args++;
  620. X    XtSetArg(args[num_args], XtNrightMargin,  &right_margin);  num_args++;
  621. X    XtGetValues(wp->w, args, num_args);
  622. X
  623. X    /* font height is ascent + descent */
  624. X    wp->pixel_height = 2 * (fs->ascent + fs->descent) +
  625. X                        top_margin + bottom_margin;
  626. X    wp->pixel_width  = COLNO * fs->max_bounds.width +
  627. X                        left_margin + right_margin;
  628. X
  629. X    /* Set the new width and height. */
  630. X    num_args = 0;
  631. X    XtSetArg(args[num_args], XtNwidth,  wp->pixel_width);  num_args++;
  632. X    XtSetArg(args[num_args], XtNheight, wp->pixel_height); num_args++;
  633. X    XtSetValues(wp->w, args, num_args);
  634. X}
  635. X
  636. Xvoid
  637. Xdestroy_status_window(wp)
  638. X    struct xwindow *wp;
  639. X{
  640. X    /* If status_information is defined, then it a "text" status window. */
  641. X    if (wp->status_information) {
  642. X    nh_XtPopdown(wp->popup);
  643. X    XtDestroyWidget(wp->popup);
  644. X    free((char *) wp->status_information);
  645. X    }
  646. X    wp->type = NHW_NONE;
  647. X}
  648. X
  649. X
  650. X/*
  651. X * This assumes several things:
  652. X *    + Status has only 2 lines
  653. X *    + That both lines are updated in succession in line order.
  654. X *    + We didn't set stringInPlace on the widget.
  655. X */
  656. Xvoid
  657. Xadjust_status(wp, str)
  658. X    struct xwindow *wp;
  659. X    const char *str;
  660. X{
  661. X    Arg args[2];
  662. X    Cardinal num_args;
  663. X
  664. X    if (!wp->status_information) {
  665. X    update_fancy_status(wp);
  666. X    return;
  667. X    }
  668. X
  669. X    if (wp->cursy == 0) {
  670. X    clear_text_buffer(&wp->status_information->text);
  671. X    append_text_buffer(&wp->status_information->text, str, FALSE);
  672. X    return;
  673. X    }
  674. X    append_text_buffer(&wp->status_information->text, str, FALSE);
  675. X
  676. X    /* Set new buffer as text. */
  677. X    num_args = 0;
  678. X    XtSetArg(args[num_args], XtNstring, wp->status_information->text.text);
  679. X                                    num_args++;
  680. X    XtSetValues(wp->w, args, num_args);
  681. X}
  682. X
  683. X
  684. X/* Fancy Status -------------------------------------------------------------*/
  685. Xstatic Widget init_info_form();
  686. Xstatic Widget init_column();
  687. Xstatic void set_widths();
  688. Xstatic void get_widths();
  689. Xstatic void create_widget();
  690. Xstatic const char *width_string();
  691. Xstatic void hilight_label();
  692. Xstatic void update_val();
  693. X
  694. Xstatic int hilight_time = 1;    /* number of turns to hilight a changed value */
  695. X
  696. Xstruct X_status_value {
  697. X    char    *name;        /* text name */
  698. X    int     type;        /* status type */
  699. X    Widget  w;            /* widget of name/value pair */
  700. X    int     last_value;        /* value displayed */
  701. X    int        turn_count;        /* last time the value changed */
  702. X    boolean set;        /* if hilighed */
  703. X    boolean after_init;        /* don't hilight on first change (init) */
  704. X};
  705. X
  706. X/* valid type values */
  707. X#define SV_VALUE 0    /* displays a label:value pair */
  708. X#define SV_LABEL 1    /* displays a changable label */
  709. X#define SV_NAME  2    /* displays an unchangeable name */
  710. X
  711. X/*
  712. X * Form entry storage indices.
  713. X */
  714. X#define F_STR        0
  715. X#define F_DEX        1
  716. X#define F_CON        2
  717. X#define F_INT        3
  718. X#define F_WIS        4
  719. X#define F_CHA        5
  720. X
  721. X#define F_NAME      6
  722. X#define F_DLEVEL    7
  723. X#define F_GOLD      8
  724. X#define F_HP        9
  725. X#define F_MAXHP       10
  726. X#define F_POWER    11
  727. X#define F_MAXPOWER 12
  728. X#define F_AC       13
  729. X#define F_LEVEL    14
  730. X#define F_EXP      15
  731. X#define F_ALIGN       16
  732. X#define F_TIME     17
  733. X
  734. X#define F_HUNGER   18
  735. X#define F_CONFUSED 19
  736. X#define F_SICK       20
  737. X#define F_BLIND       21
  738. X#define F_STUNNED  22
  739. X#define F_HALLU    23
  740. X#define F_ENCUMBER 24
  741. X
  742. X#define NUM_STATS  25
  743. X
  744. X/*
  745. X * Notes:
  746. X * + Alignment needs a different init value, because -1 is an alignment.
  747. X * + Blank value is 0 and should never change.
  748. X */
  749. Xstatic struct X_status_value shown_stats[NUM_STATS] = {
  750. X    { "Strength",    SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },    /* 0*/
  751. X    { "Dexerity",    SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
  752. X    { "Constitution",    SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
  753. X    { "Intelligence",    SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
  754. X    { "Wisdom",        SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
  755. X    { "Charisma",    SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },    /* 5*/
  756. X
  757. X    { "",        SV_LABEL, (Widget) 0, -1, 0, FALSE, FALSE }, /* name */
  758. X    { "",        SV_LABEL, (Widget) 0, -1, 0, FALSE, FALSE }, /* dlvl */
  759. X    { "Gold",        SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
  760. X    { "Hit Points",    SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
  761. X    { "Max HP",        SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },    /*10*/
  762. X    { "Power",        SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
  763. X    { "Max Power",    SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
  764. X    { "Armor Class",    SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
  765. X    { "Level",        SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
  766. X    { "Experience",    SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },    /*15*/
  767. X    { "Alignment",    SV_VALUE, (Widget) 0, -2, 0, FALSE, FALSE },
  768. X    { "Time",        SV_VALUE, (Widget) 0, -2, 0, FALSE, FALSE },
  769. X
  770. X    { "",        SV_NAME,  (Widget) 0,  0, 0, FALSE, TRUE }, /* hunger*/
  771. X    { "Confused",    SV_NAME,  (Widget) 0,  1, 0, FALSE, TRUE },
  772. X    { "Sick",        SV_NAME,  (Widget) 0,  0, 0, FALSE, TRUE },    /*20*/
  773. X    { "Blind",        SV_NAME,  (Widget) 0,  0, 0, FALSE, TRUE },
  774. X    { "Stunned",    SV_NAME,  (Widget) 0,  0, 0, FALSE, TRUE },
  775. X    { "Hallucinating",    SV_NAME,  (Widget) 0,  0, 0, FALSE, TRUE },
  776. X    { "",        SV_NAME,  (Widget) 0,  0, 0, FALSE, TRUE }, /*encumbr*/
  777. X
  778. X};
  779. X
  780. X
  781. X/*
  782. X * Set all widget values to a null string.  This is used after all spacings
  783. X * have been calculated so that when the window is popped up we don't get all
  784. X * kinds of funny values being displayed.
  785. X */
  786. Xvoid
  787. Xnull_out_status()
  788. X{
  789. X    int i;
  790. X    struct X_status_value *sv;
  791. X    Arg args[1];
  792. X
  793. X    for (i = 0, sv = shown_stats; i < NUM_STATS; i++, sv++) {
  794. X    switch (sv->type) {
  795. X        case SV_VALUE:
  796. X        set_value(sv->w, "");
  797. X        break;
  798. X
  799. X        case SV_LABEL:
  800. X        case SV_NAME:
  801. X        XtSetArg(args[0], XtNlabel, "");
  802. X        XtSetValues(sv->w, args, ONE);
  803. X        break;
  804. X
  805. X        default:
  806. X        impossible("null_out_status: unknown type %d\n", sv->type);
  807. X        break;
  808. X    }
  809. X    }
  810. X}
  811. X
  812. X/* This is almost an exact duplicate of hilight_value() */
  813. Xstatic void
  814. Xhilight_label(w)
  815. X    Widget w;    /* label widget */
  816. X{
  817. X    Arg args[2];
  818. X    Pixel fg, bg;
  819. X
  820. X    XtSetArg(args[0], XtNforeground, &fg);
  821. X    XtSetArg(args[1], XtNbackground, &bg);
  822. X    XtGetValues(w, args, TWO);
  823. X
  824. X    XtSetArg(args[0], XtNforeground, bg);
  825. X    XtSetArg(args[1], XtNbackground, fg);
  826. X    XtSetValues(w, args, TWO);
  827. X}
  828. X
  829. X
  830. Xstatic void
  831. Xupdate_val(attr_rec, new_value)
  832. X    struct X_status_value *attr_rec;
  833. X    long new_value;
  834. X{
  835. X    char buf[BUFSZ];
  836. X    Arg args[4];
  837. X
  838. X    if (attr_rec->type == SV_LABEL) {
  839. X
  840. X    if (attr_rec == &shown_stats[F_NAME]) {
  841. X
  842. X        Strcpy(buf, plname);
  843. X        if ('a' <= buf[0] && buf[0] <= 'z') buf[0] += 'A'-'a';
  844. X        Strcat(buf, " the ");
  845. X#ifdef POLYSELF
  846. X        if (u.mtimedone) {
  847. X        char mname[BUFSZ];
  848. X        int k = 0;
  849. X
  850. X        Strcpy(mname, mons[u.umonnum].mname);
  851. X        while(mname[k] != 0) {
  852. X            if ((k == 0 || (k > 0 && mname[k-1] == ' ')) &&
  853. X                    'a' <= mname[k] && mname[k] <= 'z')
  854. X                mname[k] += 'A' - 'a';
  855. X            k++;
  856. X        }
  857. X        Strcat(buf, mname);
  858. X        } else
  859. X#endif
  860. X        Strcat(buf, rank_of(u.ulevel, pl_character[0], flags.female));
  861. X
  862. X    } else if (attr_rec == &shown_stats[F_DLEVEL]) {
  863. X        if (In_endgame(&u.uz)) {
  864. X        Strcpy(buf, (Is_astralevel(&u.uz) ? "Astral Plane":"End Game"));
  865. X        } else {
  866. X        Strcpy(buf, dungeons[u.uz.dnum].dname);
  867. X        Sprintf(eos(buf), ", level %d", depth(&u.uz));
  868. X        }
  869. X    } else {
  870. X        impossible("update_val: unknown label type \"%s\"",
  871. X                            attr_rec->name);
  872. X        return;
  873. X    }
  874. X
  875. X    if (strcmp(buf, attr_rec->name) == 0) return;    /* same */
  876. X
  877. X    /* Set the label. */
  878. X    Strcpy(attr_rec->name, buf);
  879. X    XtSetArg(args[0], XtNlabel, buf);
  880. X    XtSetValues(attr_rec->w, args, ONE);
  881. X
  882. X    } else if (attr_rec->type == SV_NAME) {
  883. X
  884. X    if (attr_rec->last_value == new_value) return;    /* no change */
  885. X
  886. X    attr_rec->last_value = new_value;
  887. X
  888. X    /* special cases: hunger and encumbrance */
  889. X    if (attr_rec == &shown_stats[F_HUNGER]) {
  890. X        XtSetArg(args[0], XtNlabel, hu_stat[new_value]);
  891. X    } else if (attr_rec == &shown_stats[F_ENCUMBER]) {
  892. X        XtSetArg(args[0], XtNlabel, enc_stat[new_value]);
  893. X    } else if (new_value) {
  894. X        XtSetArg(args[0], XtNlabel, attr_rec->name);
  895. X    } else {
  896. X        XtSetArg(args[0], XtNlabel, "");
  897. X    }
  898. X    XtSetValues(attr_rec->w, args, ONE);
  899. X
  900. X    } else {    /* a value pair */
  901. X    boolean force_update = FALSE;
  902. X
  903. X    /* special case: time can be enabled & disabled */
  904. X    if (attr_rec == &shown_stats[F_TIME]) {
  905. X        static boolean flagtime = TRUE;
  906. X
  907. X        if(flags.time && !flagtime) {
  908. X        set_name(attr_rec->w, shown_stats[F_TIME].name);
  909. X        force_update = TRUE;
  910. X        flagtime = flags.time;
  911. X        } else if(!flags.time && flagtime) {
  912. X        set_name(attr_rec->w, "");
  913. X        set_value(attr_rec->w, "");
  914. X        flagtime = flags.time;
  915. X        }
  916. X        if(!flagtime) return;
  917. X    }
  918. X#ifdef POLYSELF
  919. X    /* special case: when polymorphed, show "HD", disable exp */
  920. X    else if (attr_rec == &shown_stats[F_LEVEL]) {
  921. X        static boolean lev_was_poly = FALSE;
  922. X
  923. X        if (u.mtimedone && !lev_was_poly) {
  924. X        force_update = TRUE;
  925. X        set_name(attr_rec->w, "HD");
  926. X        lev_was_poly = TRUE;
  927. X        } else if (!u.mtimedone && lev_was_poly) {
  928. X        force_update = TRUE;
  929. X        set_name(attr_rec->w, shown_stats[F_LEVEL].name);
  930. X        lev_was_poly = FALSE;
  931. X        }
  932. X    } else if (attr_rec == &shown_stats[F_EXP]) {
  933. X        static boolean exp_was_poly = FALSE;
  934. X
  935. X        if (u.mtimedone && !exp_was_poly) {
  936. X        force_update = TRUE;
  937. X        set_name(attr_rec->w, "");
  938. X        set_value(attr_rec->w, "");
  939. X        exp_was_poly = TRUE;
  940. X        } else if (!u.mtimedone && exp_was_poly) {
  941. X        force_update = TRUE;
  942. X        set_name(attr_rec->w, shown_stats[F_EXP].name);
  943. X        exp_was_poly = FALSE;
  944. X        }
  945. X        if (u.mtimedone) return;    /* no display for exp when poly */
  946. X    }
  947. X#endif
  948. X
  949. X    if (attr_rec->last_value == new_value && !force_update)    /* same */
  950. X        return;
  951. X
  952. X    attr_rec->last_value = new_value;
  953. X
  954. X    /* Special cases: strength, alignment and "clear". */
  955. X    if (attr_rec == &shown_stats[F_STR]) {
  956. X        if(new_value > 18) {
  957. X        if (new_value > 118)
  958. X            Sprintf(buf,"%d", new_value-100);
  959. X        else if(new_value < 118)
  960. X            Sprintf(buf, "18/%02d", new_value-18);
  961. X        else
  962. X            Strcpy(buf, "18/**");
  963. X        } else {
  964. X        Sprintf(buf, "%d", new_value);
  965. X        }
  966. X    } else if (attr_rec == &shown_stats[F_ALIGN]) {
  967. X
  968. X        Strcpy(buf, (new_value == A_CHAOTIC) ? "Chaotic" :
  969. X            (new_value == A_NEUTRAL) ? "Neutral" :
  970. X                           "Lawful"  );
  971. X    } else {
  972. X        Sprintf(buf, "%d", new_value);
  973. X    }
  974. X    set_value(attr_rec->w, buf);
  975. X    }
  976. X
  977. X    /*
  978. X     * Now hilight the changed information.  Names, time and score don't
  979. X     * hilight.  If first time, don't hilight.  If already lit, don't do
  980. X     * it again.
  981. X     */
  982. X    if (attr_rec->type != SV_NAME && attr_rec != &shown_stats[F_TIME]) {
  983. X    if (attr_rec->after_init) {
  984. X        if(!attr_rec->set) {
  985. X        if (attr_rec->type == SV_LABEL)
  986. X            hilight_label(attr_rec->w);
  987. X        else
  988. X            hilight_value(attr_rec->w);
  989. X        attr_rec->set = TRUE;
  990. X        }
  991. X        attr_rec->turn_count = 0;
  992. X    } else {
  993. X        attr_rec->after_init = TRUE;
  994. X    }
  995. X    }
  996. X}
  997. X
  998. X/*
  999. X * Update the displayed status.  The current code in botl.c updates
  1000. X * two lines of information.  Both lines are always updated one after
  1001. X * the other.  So only do our update when we update the second line.
  1002. X *
  1003. X * Information on the first line:
  1004. X *    name, attributes, alignment, score
  1005. X *
  1006. X * Not done: score
  1007. X *
  1008. X * Information on the second line:
  1009. X *     dlvl, gold, hp, power, ac, {level & exp or HD **}
  1010. X *     status (hunger, conf, halu, stun, sick, blind), time, encumbrance
  1011. X *
  1012. X * [**] HD is shown instead of level and exp if POLYSELF is defined and
  1013. X *    mtimedone is non-zero.
  1014. X */
  1015. Xstatic void
  1016. Xupdate_fancy_status(wp)
  1017. X    struct xwindow *wp;
  1018. X{
  1019. X    const struct X_status_value *sv;
  1020. X    long val;
  1021. X    int i;
  1022. X
  1023. X    if (wp->cursy != 0) return;    /* do a complete update when line 0 is done */
  1024. X
  1025. X#ifdef GCC_WARN
  1026. X    val = 0;
  1027. X#endif
  1028. X
  1029. X    for (i = 0, sv = shown_stats; i < NUM_STATS; i++, sv++) {
  1030. X    switch (i) {
  1031. X        case F_STR:        val = (long) ACURR(A_STR); break;
  1032. X        case F_DEX:        val = (long) ACURR(A_DEX); break;
  1033. X        case F_CON:        val = (long) ACURR(A_CON); break;
  1034. X        case F_INT:        val = (long) ACURR(A_INT); break;
  1035. X        case F_WIS:        val = (long) ACURR(A_WIS); break;
  1036. X        case F_CHA:        val = (long) ACURR(A_CHA); break;
  1037. X        /*
  1038. X         * Label stats.  With the exceptions of hunger and encumbrance,
  1039. X         * these are either on or off.  Pleae leave the ternary operators
  1040. X         * the way they are.  I want to specify 0 or 1, not a boolean.
  1041. X         */
  1042. X        case F_HUNGER:    val = (long) u.uhs;            break;
  1043. X        case F_CONFUSED:    val = (long) Confusion     ? 1L : 0L;    break;
  1044. X        case F_SICK:    val = (long) Sick       ? 1L : 0L;    break;
  1045. X        case F_BLIND:    val = (long) Blind       ? 1L : 0L;    break;
  1046. X        case F_STUNNED:    val = (long) Stunned       ? 1L : 0L;    break;
  1047. X        case F_HALLU:    val = (long) Hallucination ? 1L : 0L;    break;
  1048. X        case F_ENCUMBER:    val = (long) near_capacity();        break;
  1049. X
  1050. X        case F_NAME:    val = (long) 0L; break;    /* special */
  1051. X        case F_DLEVEL:    val = (long) 0L; break;    /* special */
  1052. X        case F_GOLD:    val = (long) u.ugold; break;
  1053. X#ifdef POLYSELF
  1054. X        case F_HP:        val = (long) (u.mtimedone ?
  1055. X                          (u.mh  > 0 ? u.mh  : 0):
  1056. X                          (u.uhp > 0 ? u.uhp : 0)); break;
  1057. X        case F_MAXHP:    val = (long) (u.mtimedone ? u.mhmax :
  1058. X                                u.uhpmax);  break;
  1059. X#else
  1060. X        case F_HP:        val = (long) (u.uhp > 0 ? u.uhp : 0);    break;
  1061. X        case F_MAXHP:    val = (long) u.uhpmax;    break;
  1062. X#endif
  1063. X        case F_POWER:    val = (long) u.uen;    break;
  1064. X        case F_MAXPOWER:    val = (long) u.uenmax;    break;
  1065. X        case F_AC:        val = (long) u.uac;    break;
  1066. X#ifdef POLYSELF
  1067. X        case F_LEVEL:    val = (long) (u.mtimedone ?
  1068. X                        mons[u.umonnum].mlevel :
  1069. X                        u.ulevel);        break;
  1070. X#else
  1071. X        case F_LEVEL:    val = (long) u.ulevel;    break;
  1072. X#endif
  1073. X        case F_EXP:        val = (long) u.uexp;    break;
  1074. X        case F_ALIGN:    val = (long) u.ualign.type; break;
  1075. X        case F_TIME:    val = flags.time ? (long) moves : 0L;    break;
  1076. X        default:
  1077. X        {
  1078. X        /*
  1079. X         * There is a possible infinite loop that occurs with:
  1080. X         *
  1081. X         *     impossible->pline->flush_screen->bot->bot{1,2}->
  1082. X         *     putstr->adjust_status->update_other->impossible
  1083. X         *
  1084. X         * Break out with this.
  1085. X         */
  1086. X        static boolean active = FALSE;
  1087. X        if (!active) {
  1088. X            active = TRUE;
  1089. X            impossible("update_other: unknown shown value");
  1090. X            active = FALSE;
  1091. X        }
  1092. X        break;
  1093. X        }
  1094. X    }
  1095. X    update_val(sv, val);
  1096. X    }
  1097. X}
  1098. X
  1099. X/*
  1100. X * Turn off hilighted status values after a certain amount of turns.
  1101. X */
  1102. Xvoid
  1103. Xcheck_turn_events()
  1104. X{
  1105. X    int i;
  1106. X    struct X_status_value *sv;
  1107. X
  1108. X    for (sv = shown_stats, i = 0; i < NUM_STATS; i++, sv++) {
  1109. X    if (!sv->set) continue;
  1110. X
  1111. X    if (sv->turn_count++ >= hilight_time) {
  1112. X        if (sv->type == SV_LABEL)
  1113. X        hilight_label(sv->w);
  1114. X        else
  1115. X        hilight_value(sv->w);
  1116. X        sv->set = FALSE;
  1117. X    }
  1118. X    }
  1119. X}
  1120. X
  1121. X/* Initialize alternate status ============================================= */
  1122. X
  1123. X/* Return a string for the initial width. */
  1124. Xstatic const char *
  1125. Xwidth_string(sv_index)
  1126. X    int sv_index;
  1127. X{
  1128. X    switch (sv_index) {
  1129. X    case F_STR:    return "018/**";
  1130. X    case F_DEX:
  1131. X    case F_CON:
  1132. X    case F_INT:
  1133. X    case F_WIS:
  1134. X    case F_CHA:    return "088";    /* all but str never get bigger */
  1135. X
  1136. X    case F_HUNGER:    return shown_stats[F_HUNGER].name;
  1137. X    case F_CONFUSED:return shown_stats[F_CONFUSED].name;
  1138. X    case F_SICK:    return shown_stats[F_SICK].name;
  1139. X    case F_BLIND:    return shown_stats[F_BLIND].name;
  1140. X    case F_STUNNED: return shown_stats[F_STUNNED].name;
  1141. X    case F_HALLU:    return shown_stats[F_HALLU].name;
  1142. X    case F_ENCUMBER:return shown_stats[F_ENCUMBER].name;
  1143. X
  1144. X    case F_NAME:
  1145. X    case F_DLEVEL:    return "";
  1146. X    case F_HP:
  1147. X    case F_MAXHP:    return "9999";
  1148. X    case F_POWER:
  1149. X    case F_MAXPOWER:return "999";
  1150. X    case F_AC:    return "-99";
  1151. X    case F_LEVEL:    return "99";
  1152. X    case F_GOLD:
  1153. X    case F_EXP:    return "4294967295";    /* max ulong */
  1154. X    case F_ALIGN:    return "Neutral";
  1155. X    case F_TIME:    return "4294967295";    /* max ulong */
  1156. X    }
  1157. X    impossible("width_string: unknown index %d\n", sv_index);
  1158. X    return "";
  1159. X}
  1160. X
  1161. Xstatic void
  1162. Xcreate_widget(parent, sv, sv_index)
  1163. X    Widget parent;
  1164. X    struct X_status_value *sv;
  1165. X    int sv_index;
  1166. X{
  1167. X    Arg args[4];
  1168. X    Cardinal num_args;
  1169. X
  1170. X    switch (sv->type) {
  1171. X    case SV_VALUE:
  1172. X        sv->w = create_value(parent, sv->name);
  1173. X        set_value(sv->w, width_string(sv_index));
  1174. X        break;
  1175. X    case SV_LABEL:
  1176. X        /* Labels get their own buffer. */
  1177. X        sv->name = (char *) alloc(BUFSZ);
  1178. X        sv->name[0] = '\0';
  1179. X
  1180. X        num_args = 0;
  1181. X        XtSetArg(args[num_args], XtNborderWidth, 0);    num_args++;
  1182. X        XtSetArg(args[num_args], XtNinternalHeight, 0);    num_args++;
  1183. X        sv->w = XtCreateManagedWidget(
  1184. X                sv_index == F_NAME ? "name" : "dlevel",
  1185. X                labelWidgetClass,
  1186. X                parent,
  1187. X                args, num_args);
  1188. X        break;
  1189. X    case SV_NAME:
  1190. X        num_args = 0;
  1191. X        XtSetArg(args[num_args], XtNborderWidth, 0);    num_args++;
  1192. X        XtSetArg(args[num_args], XtNinternalHeight, 0);    num_args++;
  1193. X        sv->w = XtCreateManagedWidget(sv->name,
  1194. X                    labelWidgetClass,
  1195. X                    parent,
  1196. X                    args, num_args);
  1197. X        break;
  1198. X    default:
  1199. X        panic("create_widget: unknown type %d", sv->type);
  1200. X    }
  1201. X}
  1202. X
  1203. X/*
  1204. X * Get current width of value.  width2p is only valid for SV_LABEL types.
  1205. X */
  1206. Xstatic void
  1207. Xget_widths(sv, width1p, width2p)
  1208. X    struct X_status_value *sv;
  1209. X    int *width1p, *width2p;
  1210. X{
  1211. X    Arg args[1];
  1212. X    Dimension width;
  1213. X
  1214. X    switch (sv->type) {
  1215. X    case SV_VALUE:
  1216. X        *width1p = get_name_width(sv->w);
  1217. X        *width2p = get_value_width(sv->w);
  1218. X        break;
  1219. X    case SV_LABEL:
  1220. X    case SV_NAME:
  1221. X        XtSetArg(args[0], XtNwidth, &width);
  1222. X        XtGetValues(sv->w, args, ONE);
  1223. X        *width1p = width;
  1224. X        *width2p = 0;
  1225. X        break;
  1226. X    default:
  1227. X        panic("get_widths: unknown type %d", sv->type);
  1228. X    }
  1229. X}
  1230. X
  1231. Xstatic void
  1232. Xset_widths(sv, width1, width2)
  1233. X    struct X_status_value *sv;
  1234. X    int width1, width2;
  1235. X{
  1236. X    Arg args[1];
  1237. X
  1238. X    switch (sv->type) {
  1239. X    case SV_VALUE:
  1240. X        set_name_width(sv->w, width1);
  1241. X        set_value_width(sv->w, width2);
  1242. X        break;
  1243. X    case SV_LABEL:
  1244. X    case SV_NAME:
  1245. X        XtSetArg(args[0], XtNwidth, (width1+width2));
  1246. X        XtSetValues(sv->w, args, ONE);
  1247. X        break;
  1248. X    default:
  1249. X        panic("set_widths: unknown type %d", sv->type);
  1250. X    }
  1251. X}
  1252. X
  1253. Xstatic Widget
  1254. Xinit_column(name, parent, top, left, col_indices)
  1255. X    char *name;
  1256. X    Widget parent, top, left;
  1257. X    int *col_indices;
  1258. X{
  1259. X    Widget form;
  1260. X    Arg args[4];
  1261. X    Cardinal num_args;
  1262. X    int max_width1, width1, max_width2, width2;
  1263. X    int *ip;
  1264. X    struct X_status_value *sv;
  1265. X
  1266. X    num_args = 0;
  1267. X    if (top != (Widget) 0) {
  1268. X    XtSetArg(args[num_args], XtNfromVert, top);        num_args++;
  1269. X    }
  1270. X    if (left != (Widget) 0) {
  1271. X    XtSetArg(args[num_args], XtNfromHoriz, left);    num_args++;
  1272. X    }
  1273. X    XtSetArg(args[num_args], XtNdefaultDistance, 0);    num_args++;
  1274. X    form = XtCreateManagedWidget(name,
  1275. X                formWidgetClass,
  1276. X                parent, args, num_args);
  1277. X
  1278. X    max_width1 = max_width2 = 0;
  1279. X    for (ip = col_indices; *ip >= 0; ip++) {
  1280. X    sv = &shown_stats[*ip];
  1281. X    create_widget(form, sv, *ip);    /* will set init width */
  1282. X    if (ip != col_indices) {    /* not first */
  1283. X        num_args = 0;
  1284. X        XtSetArg(args[num_args], XtNfromVert, shown_stats[*(ip-1)].w);
  1285. X                                num_args++;
  1286. X        XtSetValues(sv->w, args, num_args);
  1287. X    }
  1288. X    get_widths(sv, &width1, &width2);
  1289. X    if (width1 > max_width1) max_width1 = width1;
  1290. X    if (width2 > max_width2) max_width2 = width2;
  1291. X    }
  1292. X    for (ip = col_indices; *ip >= 0 ; ip++) {
  1293. X    set_widths(&shown_stats[*ip], max_width1, max_width2);
  1294. X    }
  1295. X
  1296. X    /* There is room behind the end marker for the two widths. */
  1297. X    *++ip = max_width1;
  1298. X    *++ip = max_width2;
  1299. X
  1300. X    return form;
  1301. X}
  1302. X
  1303. X/*
  1304. X * These are the orders of the displayed columns.  Change to suit.  The -1
  1305. X * indicates the end of the column.  The two numbers after that are used
  1306. X * to store widths that are calculated at run-time.
  1307. X */
  1308. Xstatic int attrib_indices[] = { F_STR,F_DEX,F_CON,F_INT,F_WIS,F_CHA, -1,0,0 };
  1309. Xstatic int status_indices[] = { F_HUNGER, F_CONFUSED, F_SICK, F_BLIND,
  1310. X                F_STUNNED, F_HALLU, F_ENCUMBER, -1,0,0 };
  1311. X
  1312. Xstatic int col2_indices[] = { F_MAXHP,F_ALIGN,F_TIME,F_EXP,F_MAXPOWER,-1,0,0 };
  1313. Xstatic int col1_indices[] = { F_HP, F_AC, F_GOLD, F_LEVEL, F_POWER,   -1,0,0 };
  1314. X
  1315. X
  1316. X/*
  1317. X * Produce a form that looks like the following:
  1318. X *
  1319. X *           name
  1320. X *          dlevel
  1321. X * col1_indices[0]    col2_indices[0]
  1322. X * col1_indices[1]    col2_indices[1]
  1323. X *    .            .
  1324. X *    .            .
  1325. X * col1_indices[n]    col2_indices[n]
  1326. X */
  1327. Xstatic Widget
  1328. Xinit_info_form(parent, top, left)
  1329. X    Widget parent, top, left;
  1330. X{
  1331. X    Widget form, col1;
  1332. X    struct X_status_value *sv_name, *sv_dlevel;
  1333. X    Arg args[6];
  1334. X    Cardinal num_args;
  1335. X    int total_width, *ip;
  1336. X
  1337. X    num_args = 0;
  1338. X    if (top != (Widget) 0) {
  1339. X    XtSetArg(args[num_args], XtNfromVert, top);    num_args++;
  1340. X    }
  1341. X    if (left != (Widget) 0) {
  1342. X    XtSetArg(args[num_args], XtNfromHoriz, left);    num_args++;
  1343. X    }
  1344. X    XtSetArg(args[num_args], XtNdefaultDistance, 0);    num_args++;
  1345. X    form = XtCreateManagedWidget("status_info",
  1346. X                formWidgetClass,
  1347. X                parent,
  1348. X                args, num_args);
  1349. X
  1350. X    /* top of form */
  1351. X    sv_name = &shown_stats[F_NAME];
  1352. X    create_widget(form, sv_name, F_NAME);
  1353. X
  1354. X    /* second */
  1355. X    sv_dlevel = &shown_stats[F_DLEVEL];
  1356. X    create_widget(form, sv_dlevel, F_DLEVEL);
  1357. X
  1358. X    num_args = 0;
  1359. X    XtSetArg(args[num_args], XtNfromVert, sv_name->w);     num_args++;
  1360. X    XtSetValues(sv_dlevel->w, args, num_args);
  1361. X
  1362. X    /* two columns beneath */
  1363. X    col1 = init_column("name_col1", form, sv_dlevel->w,
  1364. X                        (Widget) 0, col1_indices);
  1365. X    (void) init_column("name_col2", form, sv_dlevel->w,
  1366. X                              col1, col2_indices);
  1367. X
  1368. X    /* Add calculated widths. */
  1369. X    for (ip = col1_indices; *ip >= 0; ip++)
  1370. X    ;    /* skip to end */
  1371. X    total_width = *++ip;
  1372. X    total_width += *++ip;
  1373. X    for (ip = col2_indices; *ip >= 0; ip++)
  1374. X    ;    /* skip to end */
  1375. X    total_width += *++ip;
  1376. X    total_width += *++ip;
  1377. X
  1378. X    XtSetArg(args[0], XtNwidth, total_width);
  1379. X    XtSetValues(sv_name->w,   args, ONE);
  1380. X    XtSetArg(args[0], XtNwidth, total_width);
  1381. X    XtSetValues(sv_dlevel->w, args, ONE);
  1382. X
  1383. X    return form;
  1384. X}
  1385. X
  1386. X/*
  1387. X * Create the layout for the fancy status.  Return a form widget that
  1388. X * contains everything.
  1389. X */
  1390. Xstatic Widget
  1391. Xcreate_fancy_status(parent, top)
  1392. X    Widget parent, top;
  1393. X{
  1394. X    Widget form;    /* The form that surrounds everything. */
  1395. X    Widget w;
  1396. X    Arg args[6];
  1397. X    Cardinal num_args;
  1398. X
  1399. X    num_args = 0;
  1400. X    if (top != (Widget) 0) {
  1401. X    XtSetArg(args[num_args], XtNfromVert, top);    num_args++;
  1402. X    }
  1403. X    XtSetArg(args[num_args], XtNdefaultDistance, 0);    num_args++;
  1404. X    XtSetArg(args[num_args], XtNborderWidth, 0);    num_args++;
  1405. X    form = XtCreateManagedWidget("fancy_status",
  1406. X                formWidgetClass,
  1407. X                parent,
  1408. X                args, num_args);
  1409. X
  1410. X    w = init_info_form(form, (Widget) 0, (Widget) 0);
  1411. X    w =    init_column("status_attributes",form, (Widget) 0, w, attrib_indices);
  1412. X    (void) init_column("status_condition", form, (Widget) 0, w, status_indices);
  1413. X    return form;
  1414. X}
  1415. X
  1416. END_OF_FILE
  1417. if test 25001 -ne `wc -c <'win/X11/winstat.c'`; then
  1418.     echo shar: \"'win/X11/winstat.c'\" unpacked with wrong size!
  1419. fi
  1420. # end of 'win/X11/winstat.c'
  1421. fi
  1422. echo shar: End of archive 76 \(of 108\).
  1423. cp /dev/null ark76isdone
  1424. MISSING=""
  1425. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  1426. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  1427. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  1428. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  1429. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  1430. 101 102 103 104 105 106 107 108 ; do
  1431.     if test ! -f ark${I}isdone ; then
  1432.     MISSING="${MISSING} ${I}"
  1433.     fi
  1434. done
  1435. if test "${MISSING}" = "" ; then
  1436.     echo You have unpacked all 108 archives.
  1437.     echo "Now execute 'rebuild.sh'"
  1438.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  1439. else
  1440.     echo You still need to unpack the following archives:
  1441.     echo "        " ${MISSING}
  1442. fi
  1443. ##  End of shell archive.
  1444. exit 0
  1445.