+++ /dev/null
-NetHack 3.7 window.txt $NHDT-Date: 1643491505 2022/01/29 21:25:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $
-
-Introduction
-
-This file documents the support for various windowing systems in
-NetHack. The support is through a standard interface, separating the
-main NetHack code from window-system specific code. The implementation
-supports multiple window systems in the same binary. Even if you only
-wish to support one window-port on your port, you will need to follow
-the instructions in Section IX to get a compilable binary.
-
-Copyright 2003, David Cohrs
-NetHack may be freely redistributed. See license for details.
-
-Contents:
- I. Window Types and Terminology
- II. Interface Specification
- III. Global variables
- IV. WINCAP preferences support
- V. New or respecified common, high level routines
- VI. Game startup
- VII. Conventions
- VIII. Implementation and Multi-window support
- IX. WINCHAIN
-
-I. Window Types and Terminology
-
-There are 4 basic window types, used to call create_nhwindow():
-
- NHW_MESSAGE (top line)
- NHW_MAP (main dungeon)
- NHW_MENU (inventory or other "corner" windows)
- NHW_TEXT (help/text, full screen paged window)
-
-The tty window-port also uses NHW_BASE (the base display) internally.
-
-(The genl_status_* routines use NHW_STATUS for backward compatibility
- when displaying status information on the bottom lines. New code
- should not use NHW_STATUS. NHW_STATUS will be phased out over time.)
-
-NHW_MENU windows can be used for either menu or text display. Their
-basic feature is that for the tty-port, if the window is small enough,
-it appears in the corner of the tty display instead of overwriting
-the whole screen. The first call to add information to the window
-will decide if it is going to be used to display a menu or text.
-If start_menu() is called, then it will be used as a menu. If
-putstr() is called, it will be used as text. Once decided, there
-is no turning back. For the tty-port, if the data is too large for
-a single screen then the data is paged (with --more--) between pages.
-Only NHW_MENU type windows can be used for menus.
-
-NHW_TEXT windows are used to display a large amount of textual data.
-This is the type of window one would use for displaying a help file,
-for example. In the tty window-port, windows of type NHW_TEXT can
-page using the DEF_PAGER, if DEF_PAGER is defined. There exists an
-assumption that the font for text windows is monospaced. The help
-files are all formatted accordingly.
-
-"window" is always of type winid. This is currently implemented as an
-integer, but doesn't necessarily have to be done that way. There are
-a few fixed window names that are known throughout the code:
-
- WIN_MESSAGE (top line)
- WIN_MAP (main dungeon)
- WIN_INVEN (inventory)
-
-Other windows are created and destroyed as needed.
-
-(The genl_status_* routines use WIN_STATUS for backward compatibility
- when displaying status information on the bottom lines. New code
- should not use WIN_STATUS, or assume its presence. NHW_STATUS will
- be phased out over time.)
-
-"Port" in this document refers to a CPU/OS/hardware platform (UNIX, MSDOS
-TOS, etc.) "window-port" refers to the windowing platform. This is
-orthogonal (e.g. UNIX might use either a tty window-port or an X11
-window-port).
-
-
-II. Interface Specification
-
-All functions below are void unless otherwise noted.
-
-A. Low-level routines:
-
-raw_print(str) -- Print directly to a screen, or otherwise guarantee that
- the user sees str. raw_print() appends a newline to str.
- It need not recognize ASCII control characters. This is
- used during startup (before windowing system initialization
- -- maybe this means only error startup messages are raw),
- for error messages, and maybe other "msg" uses. E.g.
- updating status for micros (i.e, "saving").
-raw_print_bold(str)
- -- Like raw_print(), but prints in bold/standout (if possible).
-curs(window, x, y)
- -- Next output to window will start at (x,y), also moves
- displayable cursor to (x,y). For backward compatibility,
- 1 <= x < cols, 0 <= y < rows, where cols and rows are
- the size of window.
- -- For variable sized windows, like the old status window, the
- behavior when curs() is called outside the window's limits
- is unspecified. The mac port wraps to 0, with the status
- window being 2 lines high and 80 columns wide.
- -- Still used by curs_on_u(), obsolete status updates,
- screen locating (identify, teleport).
- -- NHW_MESSAGE, NHW_MENU and NHW_TEXT windows do not
- currently support curs in the tty window-port.
-putstr(window, attr, str)
- -- Print str on the window with the given attribute. Only
- printable ASCII characters (040-0126) must be supported.
- Multiple putstr()s are output on separate lines. Attributes
- can be one of
- ATR_NONE (or 0)
- ATR_ULINE
- ATR_BOLD
- ATR_BLINK
- ATR_INVERSE
- If a window-port does not support all of these, it may map
- unsupported attributes to a supported one (e.g. map them
- all to ATR_INVERSE). putstr() may compress spaces out of
- str, break str, or truncate str, if necessary for the
- display. Where putstr() breaks a line, it has to clear
- to end-of-line.
- -- putstr should be implemented such that if two putstr()s
- are done consecutively the user will see the first and
- then the second. In the tty port, pline() achieves this
- by calling more() or displaying both on the same line.
-putmixed(window, attr, str)
- -- Print str on the window with the given attribute. In
- addition to printable ASCII characters (040-0126),
- sequences of encoded glyph values are supported.
- The glyph encoding sequence is \GXXXXNNNN, where:
- XXXX is a hexadecimal value. The value must match
- the randomly generated value for the current
- game in progress in order to be decoded.
- The value for the game in progress is stored in
- context.rndencode. This field minimizes
- unintentional decoding of player-supplied strings
- such as pet names, etc.
- NNNN is a hexadecimal value representing the glyph.
- If a window port does not yet support special handling of
- the glyph value, it can use genl_putmixed (windows.c)
- which converts the encoded glyph into a character symbol.
-
- Multiple putmixed()s are output on separate lines.
- Attributes can be one of
- ATR_NONE (or 0)
- ATR_ULINE
- ATR_BOLD
- ATR_BLINK
- ATR_INVERSE
- If a window-port does not support all of these, it may map
- unsupported attributes to a supported one (e.g. map them
- all to ATR_INVERSE). putmixed() may compress spaces out of
- str, break str, or truncate str, if necessary for the
- display. Where putmixed() breaks a line, it has to clear
- to end-of-line.
- -- putstr should be implemented such that if two putmixed()s
- are done consecutively the user will see the first and
- then the second.
-get_nh_event() -- Does window event processing (e.g. exposure events).
- A noop for the tty and X window-ports.
-int nhgetch() -- Returns a single character input from the user.
- -- In the tty window-port, nhgetch() assumes that tgetch()
- will be the routine the OS provides to read a character.
- Returned character _must_ be non-zero and it must be
- non meta-zero too (zero with the meta-bit set).
- -- If platform uses it, should check program_state.done_hup
- and immediately return ASCII 033 (escape) if it is.
- This is required if the window-port supports SAFERHANGUP.
- -- ASCII 033 must also be returned rather than EOF (applies
- mainly to the tty window-port).
- -- The program_state.done_hup flag can be set asynchronously
- when SAFERHANGUP is defined and in that case, nhgetch()
- needs to detect that the value of program_state.done_hup
- changed and also return ASCII 033 in this case.
-int nh_poskey(int *x, int *y, int *mod)
- -- Returns a single character input from the user or a
- positioning event (perhaps from a mouse). If the
- return value is non-zero, a character was typed, else,
- a position in the MAP window is returned in x, y and mod.
- mod may be one of
-
- CLICK_1 /* mouse click type 1 */
- CLICK_2 /* mouse click type 2 */
-
- The different click types can map to whatever the
- hardware supports. If no mouse is supported, this
- routine always returns a non-zero character.
- -- Otherwise follows the same behavior as nhgetch().
-
-B. High-level routines:
-
-print_glyph(window, x, y, glyphinfo, bkglyphinfo)
- -- Print a glyph found within the glyphinfo at (x,y) on the
- given window. The glyphs within the glyph_info struct are
- integers and can be mapped to whatever the window-
- port wants (symbol, font, color, attributes, ...there's
- a 1-1 map between glyphs and distinct things on the map).
- -- bkglyphinfo contains a background glyph for potential use
- by some graphical or tiled environments to allow the
- depiction to fall against a background consistent with the
- grid around x,y. If bkglyphinfo->glyph is NO_GLYPH, then
- the parameter should be ignored (do nothing with it).
- -- glyph_info struct fields:
- int glyph; /* the display entity */
- int color; /* color for window ports not using a tile */
- 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+ */
- short int symidx; /* offset into syms array */
- unsigned glyphflags; /* more detail about the entity */
-
-
-char yn_function(const char *ques, const char *choices, char default)
- -- Print a prompt made up of ques, choices and default.
- Read a single character response that is contained in
- choices or default. If choices is NULL, all possible
- inputs are accepted and returned. This overrides
- everything else. The choices are expected to be in
- lower case. Entering ESC always maps to 'q', or 'n',
- in that order, if present in choices, otherwise it maps
- to default. Entering any other quit character (SPACE,
- RETURN, NEWLINE) maps to default.
- -- If the choices string contains ESC, then anything after
- it is an acceptable response, but the ESC and whatever
- follows is not included in the prompt.
- -- If the choices string contains a '#' then accept a count.
- Place this value in the global "yn_number" and return '#'.
- -- This uses the top line in the tty window-port, other
- ports might use a popup.
- -- If choices is NULL, all possible inputs are accepted and
- returned, preserving case (upper or lower.) This means that
- if the calling function needs an exact match, it must handle
- user input correctness itself.
- -- ques should not be more than QBUFSZ-1 characters long.
-getlin(const char *ques, char *input)
- -- Prints ques as a prompt and reads a single line of text,
- up to a newline. The string entered is returned without the
- newline. ESC is used to cancel, in which case the string
- "\033\000" is returned.
- -- getlin() must call flush_screen(1) before doing anything.
- -- This uses the top line in the tty window-port, other
- ports might use a popup.
- -- getlin() can assume the input buffer is at least BUFSZ
- bytes in size and must truncate inputs to fit, including
- the nul character.
-int get_ext_cmd(void)
- -- Get an extended command in a window-port specific way.
- An index into extcmdlist[] is returned on a successful
- selection, -1 otherwise.
-player_selection()
- -- Do a window-port specific player type selection. If
- player_selection() offers a Quit option, it is its
- responsibility to clean up and terminate the process.
- You need to fill in pl_character[0].
-display_file(str, boolean complain)
- -- Display the file named str. Complain about missing files
- iff complain is TRUE.
-update_inventory(arg)
- -- For an argument of 0:
- -- Indicate to the window port that the inventory has
- been changed.
- -- Merely calls display_inventory() for window-ports
- that leave the window up, otherwise empty.
- -- or for a non-zero argument:
- -- Prompts the user for a menu scrolling action and
- executes that.
- -- May repeat until user finishes (typically by using
- <return> or <esc> but interface may use other means).
-doprev_message()
- -- Display previous messages. Used by the ^P command.
- -- On the tty-port this scrolls WIN_MESSAGE back one line.
-
-update_positionbar(char *features)
- -- Optional, POSITIONBAR must be defined. Provide some
- additional information for use in a horizontal
- position bar (most useful on clipped displays).
- Features is a series of char pairs. The first char
- in the pair is a symbol and the second char is the
- column where it is currently located.
- A '<' is used to mark an upstairs, a '>'
- for a downstairs, and an '@' for the current player
- location. A zero char marks the end of the list.
-
-
-C. Window Utility Routines
-
-init_nhwindows(int* argcp, char** argv)
- -- Initialize the windows used by NetHack. This can also
- create the standard windows listed at the top, but does
- not display them.
- -- Any commandline arguments relevant to the windowport
- should be interpreted, and *argcp and *argv should
- be changed to remove those arguments.
- -- When the message window is created, the variable
- iflags.window_inited needs to be set to TRUE. Otherwise
- all plines() will be done via raw_print().
- ** Why not have init_nhwindows() create all of the "standard"
- ** windows? Or at least all but WIN_INFO? -dean
-exit_nhwindows(str)
- -- Exits the window system. This should dismiss all windows,
- except the "window" used for raw_print(). str is printed
- if possible.
-window = create_nhwindow(type)
- -- Create a window of type "type."
-clear_nhwindow(window)
- -- Clear the given window, when appropriate.
-display_nhwindow(window, boolean blocking)
- -- Display the window on the screen. If there is data
- pending for output in that window, it should be sent.
- If blocking is TRUE, display_nhwindow() will not
- return until the data has been displayed on the screen,
- and acknowledged by the user where appropriate.
- -- All calls are blocking in the tty window-port.
- -- Calling display_nhwindow(WIN_MESSAGE,???) will do a
- --more--, if necessary, in the tty window-port.
-destroy_nhwindow(window)
- -- Destroy will dismiss the window if the window has not
- already been dismissed.
-start_menu(window, unsigned long mbehavior)
- -- Start using window as a menu. You must call start_menu()
- before add_menu(). After calling start_menu() you may not
- putstr() to the window. Only windows of type NHW_MENU may
- be used for menus.
- -- mbehavior allows flags to be passed to alter the appearance
- and/or behavior of the menu.
-add_menu(windid window, glyphinfo, const anything identifier, char accelerator,
- char groupacc, int attr, char *str,
- unsigned itemflags)
- -- Add a text line str to the given menu window. If identifier
- is 0, then the line cannot be selected (e.g. a title).
- Otherwise, identifier is the value returned if the line is
- selected. Accelerator is a keyboard key that can be used
- to select the line. If the accelerator of a selectable
- item is 0, the window system is free to select its own
- accelerator. It is up to the window-port to make the
- accelerator visible to the user (e.g. put "a - " in front
- of str). The value attr is the same as in putstr().
- -- glyphinfo (glyph_info type) may optionally contain a glyph
- to accompany the line. If a window port cannot
- or does not want to display it, this is OK. If there is no
- glyph provided, then the value of glyphinfo->glyph will
- be NO_GLYPH.
- -- All accelerators should be in the range [A-Za-z],
- but there are a few exceptions such as the tty player
- selection code which uses '*'.
- -- It is expected that callers do not mix accelerator
- choices. Either all selectable items have an accelerator
- or let the window system pick them. Don't do both.
- -- Groupacc is a group accelerator. It may be any character
- outside of the standard accelerator (see above) or a
- number. If 0, the item is unaffected by any group
- accelerator. If this accelerator conflicts with
- the menu command (or their user defined aliases), it loses.
- The menu commands and aliases take care not to interfere
- with the default object class symbols.
- -- itemflags on this item (such as MENU_ITEMFLAGS_SELECTED etc.).
-
-end_menu(window, prompt)
- -- Stop adding entries to the menu and flushes the window
- to the screen (brings to front?). Prompt is a prompt
- to give the user. If prompt is NULL, no prompt will
- be printed.
- ** This probably shouldn't flush the window any more (if
- ** it ever did). That should be select_menu's job. -dean
-int select_menu(windid window, int how, menu_item **selected)
- -- Return the number of items selected; 0 if none were chosen,
- -1 when explicitly cancelled. If items were selected, then
- selected is filled in with an allocated array of menu_item
- structures, one for each selected line. The caller must
- free this array when done with it. The "count" field
- of selected is a user supplied count. If the user did
- not supply a count, then the count field is filled with
- -1 (meaning all). A count of zero is equivalent to not
- being selected and should not be in the list. If no items
- were selected, then selected is NULL'ed out. How is the
- mode of the menu. Three valid values are PICK_NONE,
- PICK_ONE, and PICK_ANY, meaning: nothing is selectable,
- only one thing is selectable, and any number valid items
- may selected. If how is PICK_NONE, this function should
- never return anything but 0 or -1.
- -- You may call select_menu() on a window multiple times --
- the menu is saved until start_menu() or destroy_nhwindow()
- is called on the window.
- -- Note that NHW_MENU windows need not have select_menu()
- called for them. There is no way of knowing whether
- select_menu() will be called for the window at
- create_nhwindow() time.
-char message_menu(char let, int how, const char *mesg)
- -- tty-specific hack to allow single line context-sensitive
- help to behave compatibly with multi-line help menus.
- -- This should only be called when a prompt is active; it
- sends `mesg' to the message window. For tty, it forces
- a --More-- prompt and enables `let' as a viable keystroke
- for dismissing that prompt, so that the original prompt
- can be answered from the message line "help menu".
- -- Return value is either `let', '\0' (no selection was made),
- or '\033' (explicit cancellation was requested).
- -- Interfaces which issue prompts and messages to separate
- windows typically won't need this functionality, so can
- substitute genl_message_menu (windows.c) instead.
-
-D. Status Display Routines
-
-status_init() -- core calls this to notify the window port that a status
- display is required. The window port should perform
- the necessary initialization in here, allocate memory, etc.
-status_enablefield(int fldindex, char fldname, char fieldfmt, boolean enable)
- -- notifies the window port which fields it is authorized to
- display.
- -- This may be called at any time, and is used
- to disable as well as enable fields, depending on the
- value of the final argument (TRUE = enable).
- -- fldindex could be one of the following from botl.h:
- BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH,
- BL_ALIGN, BL_SCORE, BL_CAP, BL_GOLD, BL_ENE, BL_ENEMAX,
- BL_XP, BL_AC, BL_HD, BL_TIME, BL_HUNGER, BL_HP, BL_HPMAX,
- BL_LEVELDESC, BL_EXP, BL_CONDITION
- -- There are MAXBLSTATS status fields (from botl.h)
-status_update(int fldindex, genericptr_t ptr, int chg, int percentage, \
- int color, long *colormasks)
- -- update the value of a status field.
- -- the fldindex identifies which field is changing and
- is an integer index value from botl.h
- -- fldindex could be any one of the following from botl.h:
- BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH,
- BL_ALIGN, BL_SCORE, BL_CAP, BL_GOLD, BL_ENE, BL_ENEMAX,
- BL_XP, BL_AC, BL_HD, BL_TIME, BL_HUNGER, BL_HP, BL_HPMAX,
- BL_LEVELDESC, BL_EXP, BL_CONDITION
- -- fldindex could also be BL_FLUSH (-1), which is not really
- a field index, but is a special trigger to tell the
- windowport that it should output all changes received
- to this point. It marks the end of a bot() cycle.
- -- fldindex could also be BL_RESET (-2), which is not really
- a field index, but is a special advisory to to tell the
- windowport that it should redisplay all its status fields,
- even if no changes have been presented to it.
- -- ptr is usually a "char *", unless fldindex is BL_CONDITION.
- If fldindex is BL_CONDITION, then ptr is a long value with
- any or none of the following bits set (from botl.h):
- BL_MASK_BAREH 0x00000001L
- BL_MASK_BLIND 0x00000002L
- BL_MASK_BUSY 0x00000004L
- BL_MASK_CONF 0x00000008L
- BL_MASK_DEAF 0x00000010L
- BL_MASK_ELF_IRON 0x00000020L
- BL_MASK_FLY 0x00000040L
- BL_MASK_FOODPOIS 0x00000080L
- BL_MASK_GLOWHANDS 0x00000100L
- BL_MASK_GRAB 0x00000200L
- BL_MASK_HALLU 0x00000400L
- BL_MASK_HELD 0x00000800L
- BL_MASK_ICY 0x00001000L
- BL_MASK_INLAVA 0x00002000L
- BL_MASK_LEV 0x00004000L
- BL_MASK_PARLYZ 0x00008000L
- BL_MASK_RIDE 0x00010000L
- BL_MASK_SLEEPING 0x00020000L
- BL_MASK_SLIME 0x00040000L
- BL_MASK_SLIPPERY 0x00080000L
- BL_MASK_STONE 0x00100000L
- BL_MASK_STRNGL 0x00200000L
- BL_MASK_STUN 0x00400000L
- BL_MASK_SUBMERGED 0x00800000L
- BL_MASK_TERMILL 0x01000000L
- BL_MASK_TETHERED 0x02000000L
- BL_MASK_TRAPPED 0x04000000L
- BL_MASK_UNCONSC 0x08000000L
- BL_MASK_WOUNDEDL 0x10000000L
- BL_MASK_HOLDING 0x20000000L
- -- The value passed for BL_GOLD includes a leading
- symbol for GOLD "$:nnn". If the window port needs to use
- the textual gold amount without the leading "$:" the port
- will have to add 2 to the passed "ptr" for the BL_GOLD case.
- -- color is an unsigned int.
- int & 0x00FF = color CLR_*
- int >> 8 = attribute (if any)
-
- This contains the color and attribute that the field should
- be displayed in.
-
- This is relevant for everything except BL_CONDITION.
- If fldindex is BL_CONDITION, this parameter should be
- ignored, as condition hilighting is done via the next
- colormasks parameter instead.
-
- -- colormasks - pointer to cond_hilites[] array of colormasks.
- Only relevant for BL_CONDITION fldindex. The window port
- should ignore this parameter for other fldindex values.
-
- Each condition bit must only ever appear in one of the
- CLR_ array members, but can appear in multiple HL_ATTCLR_
- offsets (because more than one attribute can co-exist).
-
- For the user's chosen set of BL_MASK_ condition bits,
- They are stored internally in the cond_hilites[] array,
- at the array offset aligned to the color those condition
- bits should display in.
-
- For example, if the user has chosen to display strngl
- and stone and termill in red and inverse,
-
- BL_MASK_SLIME 0x00000002
- BL_MASK_STRNGL 0x00000004
- BL_MASK_TERMILL 0x00000010
-
- The bitmask corresponding to those conditions is
- 0x00000016 (or 00010110 in binary) and the color
- is at offset 1 (CLR_RED).
-
- Here is how that is stored in the cond_hilites[] array:
-
- +------+----------------------+--------------------+
- |array | | |
- |offset| macro for indexing | bitmask |
- |------+----------------------+--------------------+
- | 0 | CLR_BLACK | |
- +------+----------------------+--------------------+
- | 1 | CLR_RED | 00010110 |
- +------+----------------------+--------------------+
- | 2 | CLR_GREEN | |
- +------+----------------------+--------------------+
- | 3 | CLR_BROWN | |
- +------+----------------------+--------------------+
- | 4 | CLR_BLUE | |
- +------+----------------------+--------------------+
- | 5 | CLR_MAGENTA | |
- +------+----------------------+--------------------+
- | 6 | CLR_CYAN | |
- +------+----------------------+--------------------+
- | 7 | CLR_GRAY | |
- +------+----------------------+--------------------+
- | 8 | NO_COLOR | |
- +------+----------------------+--------------------+
- | 9 | CLR_ORANGE | |
- +------+----------------------+--------------------+
- | 10 | CLR_BRIGHT_GREEN | |
- +------+----------------------+--------------------+
- | 11 | CLR_BRIGHT_YELLOW | |
- +------+----------------------+--------------------+
- | 12 | CLR_BRIGHT_BLUE | |
- +------+----------------------+--------------------+
- | 13 | CLR_BRIGHT_MAGENTA | |
- +------+----------------------+--------------------+
- | 14 | CLR_BRIGHT_CYAN | |
- +------+----------------------+--------------------+
- | 15 | CLR_WHITE | |
- +------+----------------------+--------------------+
- | 16 | HL_ATTCLR_DIM | | CLR_MAX
- +------+----------------------+--------------------+
- | 17 | HL_ATTCLR_BLINK | |
- +------+----------------------+--------------------+
- | 18 | HL_ATTCLR_ULINE | |
- +------+----------------------+--------------------+
- | 19 | HL_ATTCLR_INVERSE | 00010110 |
- +------+----------------------+--------------------+
- | 20 | HL_ATTCLR_BOLD | |
- +------+----------------------+--------------------+
- | 21 | beyond array boundary| | BL_ATTCLR_MAX
-
- The window port can AND (&) the bits passed in the
- ptr argument to status_update() with any non-zero
- entries in the cond_hilites[] array to determine
- the color and attributes for displaying the
- condition on the screen for the user.
-
- If the bit for a particular condition does not
- appear in any of the cond_hilites[] array offsets,
- that condition should be displayed in the default
- color and attributes.
-
-status_finish() -- called when it is time for the window port to tear down
- the status display and free allocated memory, etc.
-
-
-E. Misc. Routines
-
-make_sound(???) -- To be determined later. THIS IS CURRENTLY UN-IMPLEMENTED.
-nhbell() -- Beep at user. [This will exist at least until sounds are
- redone, since sounds aren't attributable to windows anyway.]
-mark_synch() -- Don't go beyond this point in I/O on any channel until
- all channels are caught up to here. Can be an empty call
- for the moment
-wait_synch() -- Wait until all pending output is complete (*flush*() for
- streams goes here).
- -- May also deal with exposure events etc. so that the
- display is OK when return from wait_synch().
-delay_output() -- Causes a visible delay of 50ms in the output.
- Conceptually, this is similar to wait_synch() followed
- by a nap(50ms), but allows asynchronous operation.
-askname() -- Ask the user for a player name.
-cliparound(x, y)-- Make sure that the user is more-or-less centered on the
- screen if the playing area is larger than the screen.
- -- This function is only defined if CLIPPING is defined.
-number_pad(state)
- -- Initialize the number pad to the given state.
-suspend_nhwindows(str)
- -- Prepare the window to be suspended.
-resume_nhwindows()
- -- Restore the windows after being suspended.
-can_suspend() -- Tell the core if the window system will allow the game
- to be suspended now. If unconditionally yes or no, use
- genl_can_suspend_yes() or genl_can_suspend_no().
-
-start_screen() -- Only used on Unix tty ports, but must be declared for
- completeness. Sets up the tty to work in full-screen
- graphics mode. Look at win/tty/termcap.c for an
- example. If your window-port does not need this function
- just declare an empty function.
-end_screen() -- Only used on Unix tty ports, but must be declared for
- completeness. The complement of start_screen().
-
-outrip(winid, int, time_t)
- -- The tombstone code. If you want the traditional code use
- genl_outrip for the value and check the #if in rip.c.
-
-preference_update(preference)
- -- The player has just changed one of the wincap preference
- settings, and the NetHack core is notifying your window
- port of that change. If your window-port is capable of
- dynamically adjusting to the change then it should do so.
- Your window-port will only be notified of a particular
- change if it indicated that it wants to be by setting the
- corresponding bit in the wincap mask.
-
-getmsghistory(init)
- -- This is used to preserve message history between games by
- obtaining the messages from the window port so that the
- core can put them into the savefile.
- The routine is called repeatedly from the core save routine,
- and the window port routine is expected to successively
- return each message that it wants the game to store in the
- savefile, starting with the oldest message first, finishing
- with the most recent.
- If init is TRUE, start over again from most recent message.
-
-putmsghistory(msg)
- -- This is the counterpart to getmsghistory() for restores
- used to reload the port's message recall buffer.
- The routine is called repeatedly from the core restore
- routine, starting with the oldest message first, and
- finishing with the most recent one that it read from the
- savefile. The window port routine is expected to load the
- message recall buffers in such a way that the ordering
- remains correct. The window port routine should make no
- assumptions about how
- many messages are forthcoming, nor should it assume that
- another message will follow this one, so it must be careful
- to keep all pointers/indexes intact at the end of each call.
- If the window port receives more messages that can fit in
- its buffers, it is expected to scroll away the oldest from
- its buffers, much like it would with new messages being
- produced.
-
-
-III. Global variables
-
-The following global variables are defined in decl.c and must be used by
-the window interface to the rest of NetHack.
-
-char toplines[BUFSZ] Contains the last message printed to the WIN_MESSAGE
- window, used by Norep().
-winid WIN_MESSAGE, WIN_MAP, WIN_INVEN
- The three standard windows.
- There is also a window called WIN_STATUS that is used
- only for backward compatibility in the genl_status_*
- set of generic status display functions.
-char *AE, *AS; Checked in options.c to see if we should load and
- switch to DECGraphics symset. It is #ifdefed VMS
- and UNIX.
-int LI, CO; Set in sys/unix/ioctl.c.
-
-The following appears to be Unix specific. Other ports using the tty
-window-port should also declare this variable in one of your sys/*.c files.
-
-short ospeed; Set and declared in sys/unix/unixtty.c (don't
- know about other sys files).
-
-The following global variable is defined in options.c. It equates a
-list of wincap option names with their associated bit-mask [see
-section IV WINCAP preferences support]. The array is zero-terminated.
-
-struct wc_Opt wc_options[];
- One entry for each available WINCAP option.
- Each entry has a wc_name field and a wc_bit
- field.
-
-IV. WINCAP preferences support
-
-Starting with NetHack 3.4.0, the window interface was enhanced to provide
-a common way of setting window port user preferences from the config file,
-and from the command line for some settings.
-
-The wincap preference settings all have their underlying values stored
-in iflags fields. The names of the wincap related fields are all pre-
-fixed with wc_ or wc2_ to make it easy to identify them. Your window
-port can access the fields directly.
-
-Your window port identifies what options it will react to and support
-by setting bits in the window_procs wincap mask and/or wincap2 mask.
-Your window port can also fill in the color-availability table for
-the window port, has_color[CLR_MAX] to flag the colors it supports
-1 it does, or 0 it doesn't. [CLR_MAX is 16 as of 3.6.3.]
-
-See section IX for details of where the wincap masks reside.
-
-Two things control whether any preference setting appears in the
-'O' command options menu during the game:
- 1. The option must be marked as being supported by having its
- bit set in the window_procs wincap or wincap2 mask.
- 2. The option must have its optflag field set to set_in_game in order
- to be able to set the option, or marked set_gameview if you just
- want to reveal what the option is set to.
-Both conditions must be true to be able to see or set the option from
-within NetHack.
-
-The default values for the optflag field for all the options are
-hard-coded into the option in options.c. The default value for
-the wc_ options can be altered by calling
- set_wc_option_mod_status(optmask, status)
-The default value for the wc2_ options can be altered by calling
- set_wc2_option_mod_status(optmask, status)
-In each case, set the option modification status to one of set_in_config,
-set_gameview, or set_in_game.
-
-The setting of any wincap or wincap2 option is handled by the NetHack
-core option processing code. You do not have to provide a parser in
-your window port, nor should you set the values for the
-iflags.wc_* and iflags.wc2_* fields directly within the port code.
-The port code should honor whatever values were put there by the core
-when processing options, either in the config file, or by the 'O' command.
-
-You may be wondering what values your window port will find in the
-iflags.wc_* and iflags.wc2_* fields for options that the user has not
-specified in his/her config file. Put another way, how does your port code
-tell if an option has not been set? The next paragraph explains that.
-
-If the core does not set an option, it will still be initialized
-to its default value. Those default values for the
-iflags.wc_* and iflags.wc_* fields are:
-
- o All boolean fields are initialized to the starting
- value specified for that option in the boolopt array in
- options.c. The window-port should respect that setting
- unless it has a very good reason for not doing so.
- o All int fields are initialized to zero. Zero is not a valid
- setting for any of the int options, so if your port code
- encounters a zero there, it can assume that the preference
- option was not specified. In that case, the window-port code
- should use a default setting that the port is comfortable with.
- It should write the default setting back into the iflags.wc_*
- field. That is the only time that your window-port could should
- update those fields.
- o All "char *" fields will be null pointers. Be sure to check for
- that in your window-port code before using such a pointer, or
- you'll end up triggering a nasty fault.
-
-Here are the wincap and wincap2 preference settings that your port can choose
-to support:
-
- wincap
- +--------------------+--------------------+--------------------+--------+
- | | | iflags field | data |
- | player option | bit in wincap mask | for value | type |
- |--------------------+--------------------+--------------------+--------+
- | align_message | WC_ALIGN_MESSAGE | wc_align_message |int |
- | align_status | WC_ALIGN_STATUS | wc_align_status |int |
- | ascii_map | WC_ASCII_MAP | wc_ascii_map |boolean |
- | color | WC_COLOR | wc_color |boolean |
- | eight_bit_tty | WC_EIGHT_BIT_IN | wc_eight_bit_input |boolean |
- | font_map | WC_FONT_MAP | wc_font_map |char * |
- | font_menu | WC_FONT_MENU | wc_font_menu |char * |
- | font_message | WC_FONT_MESSAGE | wc_font_message |char * |
- | font_status | WC_FONT_STATUS | wc_font_status |char * |
- | font_text | WC_FONT_TEXT | wc_font_text |char * |
- | font_size_map | WC_FONTSIZ_MAP | wc_fontsiz_map |int |
- | font_size_menu | WC_FONTSIZ_MENU | wc_fontsiz_menu |int |
- | font_size_message | WC_FONTSIZ_MESSAGE | wc_fontsiz_message |int |
- | font_size_status | WC_FONTSIZ_STATUS | wc_fontsiz_status |int |
- | font_size_text | WC_FONTSIZ_TEXT | wc_fontsiz_text |int |
- | hilite_pet | WC_HILITE_PET | wc_hilite_pet |boolean |
- | map_mode | WC_MAP_MODE | wc_map_mode |int |
- | perm_invent | WC_PERM_INVENT | wc_perm_invent |boolean |
- | player_selection | WC_PLAYER_SELECTION| wc_player_selection|int |
- | popup_dialog | WC_POPUP_DIALOG | wc_popup_dialog |boolean |
- | preload_tiles | WC_PRELOAD_TILES | wc_preload_tiles |boolean |
- | scroll_amount | WC_SCROLL_AMOUNT | wc_scroll_amount |int |
- | scroll_margin | WC_SCROLL_MARGIN | wc_scroll_margin |int |
- | splash_screen | WC_SPLASH_SCREEN | wc_splash_screen |boolean |
- | tiled_map | WC_TILED_MAP | wc_tiled_map |boolean |
- | tile_width | WC_TILE_WIDTH | wc_tile_width |int |
- | tile_height | WC_TILE_HEIGHT | wc_tile_height |int |
- | tile_file | WC_TILE_FILE | wc_tile_file |char * |
- | use_inverse | WC_INVERSE | wc_inverse |boolean |
- | vary_msgcount | WC_VARY_MSGCOUNT | wc_vary_msgcount |int |
- | windowcolors | WC_WINDOWCOLORS | wc_foregrnd_menu |char * |
- | | | wc_backgrnd_menu |char * |
- | | | wc_foregrnd_message|char * |
- | | | wc_backgrnd_message|char * |
- | | | wc_foregrnd_status |char * |
- | | | wc_backgrnd_status |char * |
- | | | wc_foregrnd_text |char * |
- | | | wc_backgrnd_text |char * |
- | mouse | WC_MOUSE_SUPPORT | wc_mouse_support |boolean |
- +--------------------+--------------------+--------------------+--------+
-
- wincap2
- +--------------------+--------------------+--------------------+--------+
- | | | iflags field | data |
- | player option | bit in wincap mask | for value | type |
- |--------------------+--------------------+--------------------+--------+
- | fullscreen | WC2_FULLSCREEN | wc2_fullscreen |boolean |
- | guicolor | WC2_GUICOLOR | wc2_guicolor |boolean |
- | hilite_status | WC2_HILITE_STATUS | wc2_hilite_status |strings |
- | hitpointbar | WC2_HITPOINTBAR | wc2_hitpointbar |boolean |
- | menu_shift_left | WC2_MENU_SHIFT | n/a |char |
- | menu_shift_right | WC2_MENU_SHIFT | n/a |char |
- | petattr | WC2_PETATTR | wc2_petattr |int |
- | selectsaved | WC2_SELECTSAVED | wc2_selectsaved |boolean |
- | softkeyboard | WC2_SOFTKEYBOARD | wc2_softkeyboard |boolean |
- | statuslines | WC2_STATUSLINES | wc2_statuslines |int |
- | term_cols | WC2_TERM_SIZE | wc2_term_cols |int |
- | term_rows | WC2_TERM_SIZE | wc2_term_rows |int |
- | use_darkgray | WC2_DARKGRAY | wc2_darkgray |boolean |
- | windowborders | WC2_WINDOWBORDERS | wc2_windowborders |int |
- | wraptext | WC2_WRAPTEXT | wc2_wraptext |boolean |
- +--------------------+--------------------+--------------------+--------+
-
- more wincap2 for STATUS_HILITES support and control
- +--------------------------------- +---------------------------+
- | To inform the game engine | |
- | that the window port is equipped | bit to set in wincap mask |
- | to receive the following in its | |
- | x_status_update() routine | |
- |----------------------------------+---------------------------+
- | BL_FLUSH to render buffered | WC2_FLUSH_STATUS |
- | field changes now | |
- |----------------------------------+---------------------------+
- | BL_RESET to indicate that all | WC2_RESET_STATUS |
- | fields should be redone | |
- +----------------------------------+---------------------------+
-
- additional wincap2 flag bits for supported putstr() attributes
- +----------------------------------+---------------------------+
- | avoid putting message into | WC2_SUPPRESS_HIST |
- | recall history | |
- | draw extra attention to message | WC2_URGENT_MESG |
- +----------------------------------+---------------------------+
-
-align_message -- where to place message window (top, bottom, left, right)
-align_status -- where to place status display (top, bottom, left, right).
-ascii_map -- port should display an ascii map if it can.
-color -- port should display color if it can.
-eight_bit_tty -- port should allow eight bit input.
-font_map -- port should use a font by this name for map window.
-font_menu -- port should use a font by this name for menu windows.
-font_message -- port should use a font by this name for message window.
-font_size_map -- port should use this size font for the map window.
-font_size_menu -- port should use this size font for menu windows.
-font_size_message
- -- port should use this size font for the message window.
-font_size_status-- port should use this size font for the status display.
-font_size_text -- port should use this size font for text windows.
-font_status -- port should use a font by this name for status display.
-font_text -- port should use a font by this name for text windows.
-fullscreen -- port should try to use the whole screen.
-hilite_pet -- port should mark pets in some special way on the map.
-hitpointbar -- port should show a graphical bar representing hit points
-map_mode -- port should display the map in the manner specified.
-player_selection
- -- dialog or prompts for choosing character.
-popup_dialog -- port should pop up dialog boxes for input.
-preload_tiles -- port should preload tiles into memory.
-scroll_amount -- scroll this amount when scroll_margin is reached.
-scroll_margin -- port should scroll the display when the hero or cursor
- is this number of cells away from the edge of the window.
-selectsaved -- if port can display a menu of the user's saved games do so.
-softkeyboard -- handhelds should display an on-screen keyboard if possible.
-splash_screen -- port should/should not display an opening splashscreen.
-term_cols -- Terminal should size itself to specified width, if possible.
-term_rows -- Terminal should size to specified height, if possible.
-tiled_map -- port should display a tiled map if it can.
-tile_width -- port should display tiles with this width or round to
- closest if it can.
-tile_height -- port should display tiles with this height or round to
- closest if it can.
-tile_file -- open this alternative tile file. The file name is likely to
- be window-port or platform specific.
-use_inverse -- port should display inverse when NetHack asks for it.
-vary_msgcount -- port should display this number of messages at a time in
- the message window.
-windowborders -- port should display borders around main NetHack windows.
- Can be set to (1) on, (2) off, or (3) auto.
-windowcolors
- -- port should use these colors for window foreground/background
- colors. Syntax:
- menu fore/back message fore/back status fore/back text fore/back
-wraptext -- port should wrap long lines of text if they don't fit in
- the visible area of the window
-mouse_support -- port should enable mouse support if possible
-
-Whenever one of these settings is adjusted, the port is notified of a change
-to the setting by calling the port's preference_update() routine. The port
-is only notified if it has indicated that it supports that option by setting
-the option's bit in the port's wincap mask. The port can choose to adjust
-for the change to an option that it receives notification about, or ignore it.
-The former approach is recommended. If you don't want to deal with a
-user-initiated setting change, then the port should call
-set_wc_option_mod_status(mask, set_in_config) to make the option invisible to
-the user.
-
-Functions available for the window port to call:
-
-set_wc_option_mod_status(optmask, status)
- -- Adjust the optflag field for a set of wincap options to
- specify whether the port wants the option to appear
- in the 'O' command options menu, The second parameter,
- "status" can be set to set_in_config, set_gameview,
- or set_in_game (set_in_config implies that the option
- is completely hidden during the game).
-
-set_wc2_option_mod_status(optmask, status)
- -- Adjust the optflag field for a set of wincap2 options to
- specify whether the port wants the option to appear
- in the 'O' command options menu, The second parameter,
- "status" can be set to set_in_config, set_gameview,
- or set_in_game (set_in_config implies that the option
- is completely hidden during the game).
-
-set_option_mod_status(optnam, status)
- -- Adjust the optflag field for one of the core options
- that is not part of the wincap suite. A port might use
- this to override the default initialization setting for
- status specified in options.c. Note that you have to
- specify the option by name and that you can only set
- one option per call unlike set_wc_option_mod_status().
-
-
-Adding a new wincap option:
-
-To add a new wincap option, please follow all these steps:
- 1. Add the option to the wincap preference settings table above. Since
- wincap is full, your option will likely target wincap2 field.
- 2. Add the description to the paragraph below the chart.
- 3. Add the WC_ or WC2_ to the bit list in include/winprocs.h
- (in wincap2 if there is no room in wincap).
- 4. Add the wc_ or wc2_ field(s) to the iflags structure in flag.h.
- 5. Add the name and value to wc_options[] or wc2_options[] in options.c
- 6. Add an appropriate parser to parseoptions() in options.c.
- 7. Add code to display current value to get_compopt_value() in options.c.
- 8. Document the option in Guidebook.mn and Guidebook.tex.
- 9. Add the bit name to the OR'd values in your window port's winprocs struct
- wincap mask if your port supports the option.
-
-V. New or respecified common, high level routines
-
-These are not part of the interface, but mentioned here for your information.
-
-char display_inventory(lets, want_reply)
- -- Calls a start_menu()/add_menu()/select_menu() sequence.
- It returns the item selected, or '\0' if none is selected.
- Returns '\033' if the menu was canceled.
-raw_printf(str, ...)
- -- Like raw_print(), but accepts arguments like printf(). This
- routine processes the arguments and then calls raw_print().
- -- The mac version #defines error raw_printf. I think this
- is a reasonable thing to do for most ports.
-pline(str, ...)
- -- Prints a string to WIN_MESSAGE using a printf() interface.
- It has the variants You(), Your(), Norep(), and others
- in pline.c which all use the same mechanism. pline()
- requires the variable "char toplines[]" be defined; Every
- putstr() on WIN_MESSAGE must copy str to toplines[] for use
- by Norep() and pline(). If the window system is not active
- (!iflags.window_inited) pline() uses raw_print().
-
-VI. Game startup
-
-The following is the general order in which calls from main() should be made,
-as they relate to the window system. The actual code may differ, but the
-order of the calls should be the same.
-
-
-choose_windows(DEFAULT_WINDOW_SYS) /* choose a default window system */
-initoptions() /* read the resource file */
-init_nhwindows() /* initialize the window system */
-process_options(argc, argv) /* process command line options or equiv */
-if(save file is present) {
- display_gamewindows() /* create & display the game windows */
- dorestore() /* restore old game; pline()s are OK */
-} else {
- player_selection() /* select a player type using a window */
- display_gamewindows() /* create & display the game windows */
-}
-pline("Hello, welcome...");
-
-Choose_windows() is a common routine, and calling it in main() is necessary
-to initialize the function pointer table to _something_ so that calls to
-raw_print() will not fail. Choose_windows() should be called almost
-immediately upon entering main(). Look at unixmain.c for an example.
-Choose_windows will call an (optional) ini_routine with a single argument
-of WININIT to allow any needed setup. Because choose_windows() may be called
-multiple times during argument and option processing, to handle the case where
-ini_routines have side effects that need to be undone, the old ini_routine (if
-any) will be called with an argument of WININIT_UNDO before the new
-ini_routine (if any) is called (with WININIT).
-
-Display_gamewindows() is a common routine that displays the two standard
-game windows (WIN_MESSAGE, WIN_MAP), and the status display. It is normally
-called just before the "Hello, welcome" message.
-
-Process_options() is currently still unique to each port. There may be need
-in the future to make it possible to replace this on a per window-port basis.
-
-
-VII. Conventions
-
-init_nhwindows() is expected to display a gee-whiz banner window, including
-the Copyright message. It is recommended that the COPYRIGHT_BANNER_A macro
-from patchlevel.h, COPYRIGHT_BANNER_B from patchlevel.h,
-nomakedefs.copyright_banner_c internal global variable, and
-COPYRIGHT_BANNER_D macros from patchlevel.h be used for constructing the
-Copyright message.
-COPYRIGHT_BANNER_A is a quoted string that has NetHack copyright declaration,
-COPYRIGHT_BANNER_B is a quoted string that states who the copyright belongs to,
-nomakedefs.copyright_banner_c is a quoted string produced at runtime that
-includes version and build information, and
-COPYRIGHT_BANNER_D simply says "See License for details."
-Be sure to #include "patchlevel.h" to define these macros. Using
-the macros will prevent having to update the Copyright information in each
-window-port prior to each release.
-
-Ports (MSDOS, TOS, MAC, etc) _may_ use window-port specific routines in
-their port specific files, _AT_THEIR_OWN_RISK_. Since "port" and
-"window-port" are orthogonal, you make your "port" code less portable by
-using "window-port" specific routines. Every effort should be made to
-use window-port interface routines, unless there is something port
-specific that is better suited (e.g. msmsg() for MSDOS).
-
-The tty window-port is contained in win/tty, the X window port is contained
-in win/X11. The files in these directories contain _only_ window port code,
-and may be replaced completely by other window ports.
-
-
-VIII. Implementation and Multi-window support
-
-NetHack 3.2 and higher support multiple window systems in the same binary.
-When writing a new window-port, you need to follow the following guidelines:
-
-1) Pick a unique prefix to identify your window-port. For example, the tty
- window port uses "tty"; the X11 window-port uses "X11".
-2) When declaring your interface function, precede the function names with
- your unique prefix. E.g:
-
- void tty_init_nhwindows()
- {
- /* code for initializing windows in the tty port */
- }
-
- When calling window functions from within your port code, we suggest
- calling the prefixed version to avoid unnecessary overhead. However,
- you may safely call the non-prefixed version (e.g. putstr() rather than
- tty_putstr()) as long as you #include "hack.h". If you do not
- include hack.h and use the non-prefixed names, you will get compile
- or link-time errors.
-
- We also suggest declaring all functions and port-specific data with
- this prefix to avoid unexpected overlaps with other window-ports.
- The tty and X11 ports do not currently follow this suggestion, but do
- use separate non-overlapping convention for naming data and internal
- functions.
-
-3) Declare a structure, "struct window_procs prefix_procs", (with your
- prefix instead of "prefix") and fill in names of all of your
- interface functions. The first entry in this structure is the name
- of your window-port, which should be the prefix. The second entry
- is the wincap mask that identifies what window port preference
- settings your port will react to and support. The other entries
- are the function addresses.
-
- Assuming that you followed the convention in (2), you can safely copy
- the structure definition from an existing window-port and just change
- the prefixes. That will guarantee that you get the order of your
- initializations correct (not all compilers will catch out-of-order
- function pointer declarations).
-
-4) Add a #define to config.h identifying your window-port in the
- "Windowing systems" section. Follow the "prefix_GRAPHICS" convention
- for your window-port.
-
-5) Add your prefix to the list of valid prefixes listed in the "Known
- systems are" comment.
-
-6) Edit makedefs.c and add a string for your windowing system to window_opts
- inside an #ifdef prefix_GRAPHICS.
-
-7) Edit windows.c and add an external reference to your prefix_procs inside
- an #ifdef prefix_GRAPHICS. Also add an entry to the win_choices
- structure for your window-port of the form:
-
- #ifdef prefix_GRAPHICS
- { &prefix_procs, prefix_init_function },
- #endif
-
- The init_function is necessary for some compilers and systems to force
- correct linking. If your system does not need such massaging, you
- may put a null pointer here.
-
- You should declare prefix_procs and prefix_init_function as extern's
- in your win*.h file, and #include that file at the beginning of
- windows.c, also inside an #ifdef prefix_GRAPHICS. Some win*.h files
- are rather sensitive, and you might have to duplicate your
- prefix_procs and prefix_init_function's instead of including win*.h.
- The tty port includes wintty.h, the X11 port duplicates the declarations.
-
-8) If your port uses Makefile.src, add the .c and .o files and an
- appropriate comment in the section on "WINSRC" and "WINOBJ". See
- Makefile.src for the style to use. If you don't use Makefile.src,
- we suggest using a similar convention for the make-equivalent used
- on your system. Also add your new source and binaries to WINSRC and
- WINOBJ (if you want the NetHack binary to include them, that is).
-
-9) Look at your port's portmain.c (the file containing main()) and make
- sure that all of the calls match the requirements laid out in
- Section VII.
-
-Now, proceed with compilation and installation as usual. Don't forget
-to edit Makefile.src (or its equivalent) and config.h to set the
-window-ports you want in your binary, the default window-port to use,
-and the .o's needed to build a valid game.
-
-One caveat. Unfortunately, if you incorrectly specify the
-DEFAULT_WINDOW_SYS, NetHack will dump core (or whatever) without
-printing any message, because raw_print() cannot function without first
-setting the window-port.
-
-
-IX. WINCHAIN
-
-WINCHAIN is an optional facility that allows the SYSCF_FILE to specify a
-series of processors that will see each call from the core to the window
-port (and the resulting return chain). Processors are specified one at a
-time from the start of the chain (the core end) towards the window port as:
- OPTIONS=windowchain:+PROC
-where PROC is the name of the processor to add to the chain. The '+' is
-required and is part of the name of the processor (this distinguishes
-processors from window ports; in addition the '-' character is reserved for
-WINCHAIN internals).
-
-If WINCHAIN is not compiled into the NetHack binary, there is no overhead.
-
-If WINCHAIN is compiled into the NetHack binary but not used, overhead is
-limited to one function call during game setup and a trivial amount of data.
-
-Note that raw_print* calls will not go through the chain until initialization
-is complete (when *main.c calls commit_windowchain()).
-
-The only processor currently available is '+trace' which is a debugging
-facility for window ports. See the code in win/chain/wc_trace.c for
-details on where to find the log file and how to write to it from other parts
-of the code.
-
-A processor may be specified more than once; this is expected to be most
-useful for surrounding a processor being developed with before and after
-calls to +trace.