ENHANCED_SYMBOLS
A new feature, enabled by default to maximize testing, but one which can
be disabled by commenting it out in config.h
With this, some additional information is added to the glyphmap entries
in a new optional substructure called u with these fields:
ucolor RGB color for use with truecolor terminals/platforms.
A ucolor value of zero means "not set." The actual
rgb value of 0 has the 0x1000000 bit set.
u256coloridx 256 color index value for use with 256 color
terminals, the closest color match to ucolor.
utf8str Custom representation via utf-8 string (can be null).
There is a new symset included in the symbols file, called enhanced1.
Some initial code has been added to parse individual
OPTIONS=glyph:glyphid/R-G-B entries in the config file.
The glyphid can, in theory, either be an individual glyph (G_* glyphid)
for a single glyph, or it can be an existing symbol S_ value
(monster, object, or cmap symbol) to store the custom representation for
all the glyphs that match that symbol.
Examples:
OPTIONS=glyph:G_fountain/U+03A8/0-150-255
(Your platform/terminal font needs to be able to include/display the
character, of course.)
The NetHack core code does parsing and storing the customized
entries, and adding them to the glyphmap data structure.
Any window port can utilize the additional information in the glyphinfo
that is passed to them, once code is added to do so.
Also, consolidate some symbol-related code into symbols.c, and remove it from
files.c and options.c
This commit is contained in:
104
dat/symbols
104
dat/symbols
@@ -2,7 +2,7 @@
|
||||
# Copyright (c) 2006 by Michael Allison
|
||||
# NetHack may be freely redistributed. See license for details.
|
||||
#
|
||||
# Symbol sets for use in NetHack's text-based display.
|
||||
# Symbol sets and handlers for use in NetHack's text-based display.
|
||||
#
|
||||
# IBMgraphics works by specifying special characters which reside
|
||||
# outside the range of normal printable characters. It has subsets
|
||||
@@ -22,7 +22,17 @@
|
||||
# on an old graphics mode for the Curses interface and is the default
|
||||
# on that windowport if no symset is specified. The Curses interface
|
||||
# can also use DECgraphics as-is; IBMgraphics probably won't work.
|
||||
|
||||
#
|
||||
# Symsets that use the UTF8 handler work a little differently than
|
||||
# those that do not. When the UTF8 handler is in effect, any NetHack
|
||||
# glyphs that have a utf8str entry present in the runtime glyphmap[]
|
||||
# array will utilize that UTF-8 character sequence for the glyph display
|
||||
# instead of the NetHack ttychar symbol that would otherwise be used.
|
||||
# Any NetHack glyphs that don't actually have a utf8str sequence present
|
||||
# in the internal glyphmap will simply fall back to utilizing the typical
|
||||
# NetHack ttychar symbol as usual. That is true even when the UTF-8
|
||||
# handler is in effect.
|
||||
#
|
||||
# plain looks decent for room+corridor levels where there aren't a lot
|
||||
# of wall corners and ones present tend to be spread out, but it looks
|
||||
# awful for wallified mazes
|
||||
@@ -550,4 +560,94 @@ start: MACgraphics
|
||||
S_pool: \xe0
|
||||
finish
|
||||
|
||||
start: Enhanced1
|
||||
Description: Enhanced with Unicode glyphs and 24-bit color
|
||||
Restrictions: primary
|
||||
Handling: UTF8
|
||||
S_vwall: U+2502 # BOX DRAWINGS LIGHT VERTICAL
|
||||
S_hwall: U+2500 # BOX DRAWINGS LIGHT HORIZONTAL
|
||||
S_tlcorn: U+250c # BOX DRAWINGS LIGHT DOWN AND RIGHT
|
||||
S_trcorn: U+2510 # BOX DRAWINGS LIGHT DOWN AND LEFT
|
||||
S_blcorn: U+2514 # BOX DRAWINGS LIGHT UP AND RIGHT
|
||||
S_brcorn: U+2518 # BOX DRAWINGS LIGHT UP AND LEFT
|
||||
S_crwall: U+253c # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
|
||||
S_tuwall: U+2534 # BOX DRAWINGS LIGHT UP AND HORIZONTAL
|
||||
S_tdwall: U+252c # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
|
||||
S_tlwall: U+2524 # BOX DRAWINGS LIGHT VERTICAL AND LEFT
|
||||
S_trwall: U+251c # BOX DRAWINGS LIGHT VERTICAL AND RIGHT
|
||||
S_ndoor: U+00b7 # MIDDLE DOT
|
||||
S_vodoor: U+2592 # MEDIUM SHADE
|
||||
S_hodoor: U+2592 # MEDIUM SHADE
|
||||
S_bars: U+2261 # IDENTICAL TO
|
||||
S_tree: U+03a8 # GREEK CAPITAL LETTER PSI
|
||||
S_room: U+00b7 # MIDDLE DOT
|
||||
S_darkroom: U+00b7 # MIDDLE DOT
|
||||
S_upladder: U+2264 # LESS-THAN OR EQUAL TO
|
||||
S_dnladder: U+2265 # GREATER-THAN OR EQUAL TO
|
||||
S_altar: U+03A9 # GREEK CAPITAL LETTER OMEGA
|
||||
S_grave: U+2020 # DAGGER
|
||||
G_fountain: U+2320/0-150-255 # TOP HALF INTEGRAL
|
||||
S_pool: U+224b # TRIPLE TILDE
|
||||
S_ice: U+00b7 # MIDDLE DOT
|
||||
S_lava: U+224b # TRIPLE TILDE
|
||||
S_vodbridge: U+00b7 # MIDDLE DOT
|
||||
S_hodbridge: U+00b7 # MIDDLE DOT
|
||||
S_water: U+2248 # ALMOST EQUAL TO
|
||||
S_web: U+00A4 # CURRENCY SIGN
|
||||
S_vbeam: U+2502 # BOX DRAWINGS LIGHT VERTICAL
|
||||
S_hbeam: U+2500 # BOX DRAWINGS LIGHT HORIZONTAL
|
||||
S_sw_tc: U+2594 # UPPER ONE EIGHTH BLOCK
|
||||
S_sw_ml: U+258f # LEFT ONE EIGHTH BLOCK
|
||||
S_sw_mr: U+2595 # RIGHT ONE EIGHTH BLOCK
|
||||
S_sw_bc: U+2581 # LOWER ONE EIGHTH BLOCK
|
||||
S_expl_tc: U+2594 # UPPER ONE EIGHTH BLOCK
|
||||
S_expl_ml: U+258f # LEFT ONE EIGHTH BLOCK
|
||||
S_expl_mr: U+2595 # RIGHT ONE EIGHTH BLOCK
|
||||
S_expl_bc: U+2581 # LOWER ONE EIGHTH BLOCK
|
||||
G_vwall_sokoban: U+2502/0-0-190
|
||||
G_hwall_sokoban: U+2500/0-0-190
|
||||
G_tlcorn_sokoban: U+250c/0-0-190
|
||||
G_trcorn_sokoban: U+2510/0-0-190
|
||||
G_blcorn_sokoban: U+2514/0-0-190
|
||||
G_brcorn_sokoban: U+2518/0-0-190
|
||||
G_crwall_sokoban: U+253C/0-0-190
|
||||
G_tuwall_sokoban: U+2500/0-0-190
|
||||
G_tdwall_sokoban: U+252C/0-0-190
|
||||
G_tlwall_sokoban: U+2524/0-0-190
|
||||
G_trwall_sokoban: U+251C/0-0-190
|
||||
G_vwall_gehennom: U+2502/190-0-0
|
||||
G_hwall_gehennom: U+2500/190-0-0
|
||||
G_tlcorn_gehennom: U+250c/190-0-0
|
||||
G_trcorn_gehennom: U+2510/190-0-0
|
||||
G_blcorn_gehennom: U+2514/190-0-0
|
||||
G_brcorn_gehennom: U+2518/190-0-0
|
||||
G_crwall_gehennom: U+253C/190-0-0
|
||||
G_tuwall_gehennom: U+2500/190-0-0
|
||||
G_tdwall_gehennom: U+252C/190-0-0
|
||||
G_tlwall_gehennom: U+2524/190-0-0
|
||||
G_trwall_gehennom: U+251C/190-0-0
|
||||
G_vwall_knox: U+2502/150-75-0
|
||||
G_hwall_knox: U+2500/150-75-0
|
||||
G_tlcorn_knox: U+250c/150-75-0
|
||||
G_trcorn_knox: U+2510/150-75-0
|
||||
G_blcorn_knox: U+2514/150-75-0
|
||||
G_brcorn_knox: U+2518/150-75-0
|
||||
G_crwall_knox: U+253C/150-75-0
|
||||
G_tuwall_knox: U+2500/150-75-0
|
||||
G_tdwall_knox: U+252C/150-75-0
|
||||
G_tlwall_knox: U+2524/150-75-0
|
||||
G_trwall_knox: U+251C/150-75-0
|
||||
G_vwall_mines: U+2502/113-126-142
|
||||
G_hwall_mines: U+2500/113-126-142
|
||||
G_tlcorn_mines: U+250c/113-126-142
|
||||
G_trcorn_mines: U+2510/113-126-142
|
||||
G_blcorn_mines: U+2514/113-126-142
|
||||
G_brcorn_mines: U+2518/113-126-142
|
||||
G_crwall_mines: U+253C/113-126-142
|
||||
G_tuwall_mines: U+2500/113-126-142
|
||||
G_tdwall_mines: U+252C/113-126-142
|
||||
G_tlwall_mines: U+2524/113-126-142
|
||||
G_trwall_mines: U+251C/113-126-142
|
||||
finish
|
||||
|
||||
# symbols EOF
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
.ds f0 "\*(vr
|
||||
.ds f1
|
||||
.\"DO NOT REMOVE NH_DATESUB .ds f2 "DATE(%B %-d, %Y)
|
||||
.ds f2 "February 27, 2022
|
||||
.ds f2 "May 7, 2022
|
||||
.
|
||||
.\" A note on some special characters:
|
||||
.\" \(lq = left double quote
|
||||
@@ -5519,6 +5519,41 @@ So S_rock is only used for boulders and not used at all if
|
||||
overridden by the more specific S_boulder.
|
||||
.pg
|
||||
.hn 2
|
||||
Customizing Map Glyph Representations Using Unicode
|
||||
.pg
|
||||
If your platform or terminal supports the display of UTF-8 character
|
||||
sequences, you can customize your game display by assigning Unicode
|
||||
codepoint values and \fIred-green-blue\fP colors to glyph
|
||||
representations. The customizations can be specified for use with a symset that
|
||||
has a UTF8 handler within the symbols file such as the enhanced1 set, or
|
||||
individually within your nethack.rc file.
|
||||
|
||||
.pg
|
||||
The format for defining a glyph representation is:
|
||||
.SD n
|
||||
\f(CROPTIONS=glyph:glyphid\fIU+nnnn\fP/\fIR-G-B\fP\fP
|
||||
.ED
|
||||
.pg
|
||||
The window port that is active needs to provide support for displaying
|
||||
UTF-8 character sequences and explicit red-green-blue colors in order
|
||||
for the glyph representation to be visible.
|
||||
For example, the following line in your configuration file will cause
|
||||
the glyph representation for glyphid G_pool to use Unicode codepoint
|
||||
U+224B and the color represented by R-G-B value 0-0-160
|
||||
.SD n
|
||||
\f(CROPTIONS=glyph:G_pool/U+224B/0-0-160\fP
|
||||
.ED
|
||||
The list of acceptable glyphid's can be produced by
|
||||
\fBnethack \-\-dumpglyphids\fP.
|
||||
Individual NetHack glyphs can be specified using the G_ prefix,
|
||||
or you can use an S_ symbol for a glyphid and store the custom
|
||||
representation for all NetHack glyphs that would map to that
|
||||
particular symbol.
|
||||
|
||||
You will need to select a symset with a UTF8 handler to enable the
|
||||
display of the customizations, such as the Enhanced symset.
|
||||
.pg
|
||||
.hn 2
|
||||
Configuring NetHack for Play by the Blind
|
||||
.pg
|
||||
NetHack can be set up to use only standard ASCII characters for making
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
\author{Original version - Eric S. Raymond\\
|
||||
(Edited and expanded for 3.7 by Mike Stephenson and others)}
|
||||
%DO NOT REMOVE NH_DATESUB \date{DATE(%B %-d, %Y)}
|
||||
\date{February 27, 2022}
|
||||
\date{May 7, 2022}
|
||||
|
||||
\maketitle
|
||||
|
||||
@@ -6071,6 +6071,46 @@ version 3.6.0, statues are displayed as the monster they depict.
|
||||
So S\verb+_+rock is only used for boulders and not used at all if
|
||||
overridden by the more specific S\verb+_+boulder.
|
||||
|
||||
%.lp
|
||||
%.hn 2
|
||||
\subsection*{Customizing Map Glyph Representations Using Unicode}
|
||||
|
||||
%.pg
|
||||
If your platform or terminal supports the display of UTF-8 character
|
||||
sequences, you can customize your game display by assigning Unicode
|
||||
codepoint values and red-green-blue colors to glyph
|
||||
representations. The customizations can be specified for use with a symset that
|
||||
has a UTF8 handler within the symbols file such as the enhanced1 set, or
|
||||
individually within your own nethack.rc file.
|
||||
|
||||
The format for defining a glyph representation is:\\
|
||||
\begin{verbatim}
|
||||
OPTIONS=glyph:glyphid/U+nnnn/R-G-B
|
||||
\end{verbatim}
|
||||
|
||||
The window port that is active needs to provide support for displaying UTF-8
|
||||
character sequences and explicit 24-bit red-green-blue colors in order for the glyph
|
||||
representation to be visible as specified.
|
||||
|
||||
For example, the following line in your configuration file will cause
|
||||
the glyph representation for glyphid G_pool to use Unicode codepoint U+224B
|
||||
and the color represented by R-G-B value 0-0-160:\\
|
||||
\begin{verbatim}
|
||||
OPTIONS=glyph:G_pool/U+224B/0-0-160
|
||||
\end{verbatim}
|
||||
|
||||
The list of acceptable glyphid's can be produced by
|
||||
\begin{verbatim}
|
||||
nethack --glyphids
|
||||
\end{verbatim}
|
||||
Individual NetHack glyphs can be specified using the G\verb+_+ prefix,
|
||||
or you can use an S\verb+_+ symbol for a glyphid and store the custom
|
||||
representation for all NetHack glyphs that would map to that
|
||||
particular symbol.
|
||||
|
||||
You will need to select a symset with a UTF8 handler to enable the
|
||||
display of the customizations, such as the Enhanced symset.
|
||||
|
||||
%.pg
|
||||
%.hn 2
|
||||
\subsection*{Configuring {\it NetHack\/} for Play by the Blind}
|
||||
|
||||
@@ -280,6 +280,15 @@
|
||||
*/
|
||||
/* #define NODUMPENUMS */
|
||||
|
||||
/*
|
||||
* ENHANCED_SYMBOLS
|
||||
* Support the enhanced display of symbols by utilizing utf8 and 24-bit
|
||||
* color sequences. Enabled by default, but it can be disabled by
|
||||
* commenting it out.
|
||||
*/
|
||||
|
||||
#define ENHANCED_SYMBOLS
|
||||
|
||||
/*
|
||||
* If COMPRESS is defined, it should contain the full path name of your
|
||||
* 'compress' program.
|
||||
|
||||
@@ -434,7 +434,10 @@ E const char *ARGV0;
|
||||
enum earlyarg {ARG_DEBUG, ARG_VERSION, ARG_SHOWPATHS
|
||||
#ifndef NODUMPENUMS
|
||||
, ARG_DUMPENUMS
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
, ARG_DUMPGLYPHIDS
|
||||
#endif
|
||||
#endif /* NODUMPENUMS */
|
||||
#ifdef WIN32
|
||||
,ARG_WINDOWS
|
||||
#endif
|
||||
@@ -679,6 +682,11 @@ struct _cmd_queue {
|
||||
struct _cmd_queue *next;
|
||||
};
|
||||
|
||||
struct enum_dump {
|
||||
int val;
|
||||
const char *nm;
|
||||
};
|
||||
|
||||
typedef long cmdcount_nht; /* Command counts */
|
||||
|
||||
/*
|
||||
@@ -888,8 +896,11 @@ struct instance_globals {
|
||||
struct rm nowhere;
|
||||
const char *gate_str;
|
||||
|
||||
/* drawing */
|
||||
/* symbols.c */
|
||||
struct symsetentry symset[NUM_GRAPHICS];
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
struct symset_customization sym_customizations[NUM_GRAPHICS + 1]; /* adds UNICODESET */
|
||||
#endif
|
||||
int currentgraphics;
|
||||
nhsym showsyms[SYM_MAX]; /* symbols to be displayed */
|
||||
nhsym primary_syms[SYM_MAX]; /* loaded primary symbols */
|
||||
|
||||
@@ -1047,6 +1047,9 @@ extern void nh_snprintf(const char *func, int line, char *str, size_t size,
|
||||
extern int FITSint_(long long, const char *, int);
|
||||
#define FITSuint(x) FITSuint_(x, __func__, __LINE__)
|
||||
extern unsigned FITSuint_(unsigned long long, const char *, int);
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
extern int unicodeval_to_utf8str(int, uint8 *, size_t);
|
||||
#endif
|
||||
|
||||
/* ### insight.c ### */
|
||||
|
||||
@@ -1281,6 +1284,9 @@ extern int buzzmu(struct monst *, struct attack *);
|
||||
extern void runtime_info_init(void);
|
||||
extern const char *do_runtime_info(int *);
|
||||
extern void release_runtime_info(void);
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
extern void dump_glyphids(void);
|
||||
#endif
|
||||
|
||||
/* ### mhitm.c ### */
|
||||
|
||||
@@ -1828,6 +1834,10 @@ extern void synch_cursor(void);
|
||||
extern void nethack_enter_consoletty(void);
|
||||
extern void consoletty_exit(void);
|
||||
extern int set_keyhandling_via_option(void);
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
extern void tty_utf8graphics_fixup(void);
|
||||
extern void tty_ibmgraphics_fixup(void);
|
||||
#endif /* ENHANCED_SYMBOLS */
|
||||
#endif /* WIN32 */
|
||||
|
||||
/* ### o_init.c ### */
|
||||
@@ -1947,10 +1957,6 @@ extern void set_wc2_option_mod_status(unsigned long, int);
|
||||
extern void set_option_mod_status(const char *, int);
|
||||
extern int add_autopickup_exception(const char *);
|
||||
extern void free_autopickup_exceptions(void);
|
||||
extern int load_symset(const char *, int);
|
||||
extern void free_symsets(void);
|
||||
extern boolean parsesymbols(char *, int);
|
||||
extern struct symparse *match_sym(char *);
|
||||
extern void set_playmode(void);
|
||||
extern int sym_val(const char *);
|
||||
extern int query_color(const char *);
|
||||
@@ -2623,11 +2629,25 @@ extern void init_rogue_symbols(void);
|
||||
extern void init_ov_primary_symbols(void);
|
||||
extern void init_ov_rogue_symbols(void);
|
||||
extern void clear_symsetentry(int, boolean);
|
||||
extern void update_primary_symset(struct symparse *, int);
|
||||
extern void update_rogue_symset(struct symparse *, int);
|
||||
extern void update_ov_primary_symset(struct symparse *, int);
|
||||
extern void update_ov_rogue_symset(struct symparse *, int);
|
||||
extern void update_primary_symset(const struct symparse *, int);
|
||||
extern void update_rogue_symset(const struct symparse *, int);
|
||||
extern void update_ov_primary_symset(const struct symparse *, int);
|
||||
extern void update_ov_rogue_symset(const struct symparse *, int);
|
||||
extern nhsym get_othersym(int, int);
|
||||
extern boolean symset_is_compatible(enum symset_handling_types, unsigned long);
|
||||
extern void set_symhandling(char *handling, int which_set);
|
||||
extern boolean proc_symset_line(char *);
|
||||
extern int do_symset(boolean);
|
||||
extern int load_symset(const char *, int);
|
||||
extern void free_symsets(void);
|
||||
extern const struct symparse *match_sym(char *);
|
||||
extern boolean parsesymbols(char *, int);
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
extern struct customization_detail *find_matching_symset_customization(
|
||||
const char *symset_name, int custtype,
|
||||
enum graphics_sets which_set);
|
||||
extern void apply_customizations_to_symset(enum graphics_sets which_set);
|
||||
#endif
|
||||
|
||||
/* ### sys.c ### */
|
||||
|
||||
@@ -2910,6 +2930,9 @@ extern void setftty(void);
|
||||
extern void intron(void);
|
||||
extern void introff(void);
|
||||
extern void error (const char *, ...) PRINTF_F(1, 2);
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
extern void tty_utf8graphics_fixup(void);
|
||||
#endif
|
||||
#endif /* UNIX || __BEOS__ */
|
||||
|
||||
/* ### unixunix.c ### */
|
||||
@@ -2939,6 +2962,24 @@ extern int hide_privileges(boolean);
|
||||
#endif
|
||||
#endif /* UNIX */
|
||||
|
||||
/* ### utf8map.c ### */
|
||||
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
extern int glyphrep(const char *);
|
||||
extern char *mixed_to_utf8(char *buf, size_t bufsz, const char *str, int *);
|
||||
extern int match_glyph(char *);
|
||||
extern void dump_all_glyphids(FILE *fp);
|
||||
extern void fill_glyphid_cache(void);
|
||||
extern void free_glyphid_cache(void);
|
||||
extern boolean glyphid_cache_status(void);
|
||||
extern int glyphrep_to_custom_map_entries(const char *op, int *glyph);
|
||||
void free_all_glyphmap_u(void);
|
||||
int add_custom_urep_entry(const char *symset_name, int glyphidx,
|
||||
const uint8 *utf8str, long ucolor,
|
||||
enum graphics_sets which_set);
|
||||
int set_map_u(glyph_map *gm, const uint8 *utf8str, long ucolor);
|
||||
#endif /* ENHANCED_SYMBOLS */
|
||||
|
||||
/* ### vault.c ### */
|
||||
|
||||
extern void newegd(struct monst *);
|
||||
@@ -3191,6 +3232,7 @@ extern int has_color(int);
|
||||
extern int glyph2ttychar(int);
|
||||
extern int glyph2symidx(int);
|
||||
extern char *encglyph(int);
|
||||
extern int decode_glyph(const char *str, int *glyph_ptr);
|
||||
extern char *decode_mixed(char *, const char *);
|
||||
extern void genl_putmixed(winid, int, const char *);
|
||||
extern boolean menuitem_invert_test(int, unsigned, boolean);
|
||||
|
||||
@@ -237,6 +237,8 @@ struct instance_flags {
|
||||
int menuinvertmode; /* 0 = invert toggles every item;
|
||||
1 = invert skips 'all items' item */
|
||||
int menu_headings; /* ATR for menu headings */
|
||||
uint32_t colorcount; /* store how many colors terminal is capable of */
|
||||
boolean use_truecolor; /* force use of truecolor */
|
||||
#ifdef ALTMETA
|
||||
boolean altmeta; /* Alt-c sends ESC c rather than M-c */
|
||||
#endif
|
||||
@@ -389,7 +391,7 @@ struct instance_flags {
|
||||
Bitfield(save_uinwater, 1);
|
||||
Bitfield(save_uburied, 1);
|
||||
struct debug_flags debug;
|
||||
boolean windowtype_locked; /* windowtype can't change from configfile */
|
||||
boolean windowtype_locked; /* windowtype can't change from configfile */
|
||||
boolean windowtype_deferred; /* pick a windowport and store it in
|
||||
chosen_windowport[], but do not switch to
|
||||
it in the midst of options processing */
|
||||
|
||||
@@ -183,6 +183,7 @@ typedef struct {
|
||||
|
||||
#include "align.h"
|
||||
#include "dungeon.h"
|
||||
#include "wintype.h"
|
||||
#include "sym.h"
|
||||
#include "mkroom.h"
|
||||
|
||||
@@ -199,7 +200,6 @@ enum misc_arti_nums {
|
||||
|
||||
#include "objclass.h"
|
||||
#include "youprop.h"
|
||||
#include "wintype.h"
|
||||
#include "context.h"
|
||||
#include "rm.h"
|
||||
#include "botl.h"
|
||||
|
||||
@@ -218,6 +218,8 @@ opt_##a,
|
||||
&iflags.wc2_fullscreen)
|
||||
NHOPTC(gender, 8, opt_in, set_gameview, No, Yes, No, No, NoAlias,
|
||||
"your starting gender (male or female)")
|
||||
NHOPTC(glyph, 40, opt_in, set_in_game, No, Yes, Yes, No, NoAlias,
|
||||
"set representation of a glyph to a unicode value and color")
|
||||
NHOPTB(goldX, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias,
|
||||
&flags.goldX)
|
||||
NHOPTB(guicolor, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias,
|
||||
@@ -521,6 +523,8 @@ opt_##a,
|
||||
&iflags.wc2_darkgray)
|
||||
NHOPTB(use_inverse, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias,
|
||||
&iflags.wc_inverse)
|
||||
NHOPTB(use_truecolor, 0, opt_in, set_in_config, Off, Yes, No, No,
|
||||
"use_truecolour", &iflags.use_truecolor)
|
||||
NHOPTC(vary_msgcount, 20, opt_in, set_gameview, No, Yes, No, No, NoAlias,
|
||||
"show more old messages at a time")
|
||||
NHOPTB(verbose, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias,
|
||||
|
||||
@@ -25,7 +25,6 @@ enum mon_syms {
|
||||
};
|
||||
|
||||
#ifndef MAKEDEFS_C
|
||||
|
||||
/* Default characters for dungeon surroundings and furniture */
|
||||
enum cmap_symbols {
|
||||
#define PCHAR_S_ENUM
|
||||
@@ -34,6 +33,22 @@ enum cmap_symbols {
|
||||
MAXPCHARS
|
||||
};
|
||||
|
||||
/*
|
||||
* special symbol set handling types ( for invoking callbacks, etc.)
|
||||
* Must match the order of the known_handlers strings
|
||||
* in drawing.c
|
||||
*/
|
||||
|
||||
enum symset_handling_types {
|
||||
H_UNK = 0,
|
||||
H_IBM = 1,
|
||||
H_DEC = 2,
|
||||
H_CURS = 3,
|
||||
H_MAC = 4, /* obsolete; needed so that the listing of available
|
||||
* symsets by 'O' can skip it for !MAC_GRAPHICS_ENV */
|
||||
H_UTF8 = 5
|
||||
};
|
||||
|
||||
struct symdef {
|
||||
uchar sym;
|
||||
const char *explanation;
|
||||
@@ -51,7 +66,7 @@ enum symparse_range {
|
||||
};
|
||||
|
||||
struct symparse {
|
||||
unsigned range;
|
||||
enum symparse_range range;
|
||||
int idx;
|
||||
const char *name;
|
||||
};
|
||||
@@ -62,7 +77,7 @@ struct symsetentry {
|
||||
char *name; /* ptr to symset name */
|
||||
char *desc; /* ptr to description */
|
||||
int idx; /* an index value */
|
||||
int handling; /* known handlers value */
|
||||
enum symset_handling_types handling; /* known handlers value */
|
||||
Bitfield(nocolor, 1); /* don't use color if set */
|
||||
Bitfield(primary, 1); /* restricted for use as primary set */
|
||||
Bitfield(rogue, 1); /* restricted for use as rogue lev set */
|
||||
@@ -109,25 +124,41 @@ enum misc_symbols {
|
||||
*/
|
||||
#define DEFAULT_GRAPHICS 0 /* regular characters: '-', '+', &c */
|
||||
enum graphics_sets {
|
||||
PRIMARY = 0, /* primary graphics set */
|
||||
PRIMARYSET = 0, /* primary graphics set */
|
||||
ROGUESET = 1, /* rogue graphics set */
|
||||
NUM_GRAPHICS
|
||||
NUM_GRAPHICS,
|
||||
UNICODESET = NUM_GRAPHICS
|
||||
};
|
||||
|
||||
/*
|
||||
* special symbol set handling types ( for invoking callbacks, etc.)
|
||||
* Must match the order of the known_handlers strings
|
||||
* in drawing.c
|
||||
*/
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
enum customization_types { custom_none, custom_symbols, custom_ureps };
|
||||
|
||||
enum symset_handling_types {
|
||||
H_UNK = 0,
|
||||
H_IBM = 1,
|
||||
H_DEC = 2,
|
||||
H_CURS = 3,
|
||||
H_MAC = 4 /* obsolete; needed so that the listing of available
|
||||
* symsets by 'O' can skip it for !MAC_GRAPHICS_ENV */
|
||||
struct custom_symbol {
|
||||
const struct symparse *symparse;
|
||||
unsigned char val;
|
||||
};
|
||||
struct custom_urep {
|
||||
int glyphidx;
|
||||
struct unicode_representation u;
|
||||
};
|
||||
union customization_content {
|
||||
struct custom_symbol sym;
|
||||
struct custom_urep urep;
|
||||
};
|
||||
struct customization_detail {
|
||||
union customization_content content;
|
||||
struct customization_detail *next;
|
||||
};
|
||||
|
||||
|
||||
/* one set per symset_name */
|
||||
struct symset_customization {
|
||||
const char *customization_name;
|
||||
int count;
|
||||
int custtype;
|
||||
struct customization_detail *details;
|
||||
};
|
||||
#endif /* ENHANCED_SYMBOLS */
|
||||
|
||||
extern const struct symdef defsyms[MAXPCHARS]; /* defaults */
|
||||
#define WARNCOUNT 6 /* number of different warning levels */
|
||||
|
||||
@@ -127,8 +127,14 @@ extern void curses_refresh_nethack_windows(void);
|
||||
extern void curses_del_nhwin(winid wid);
|
||||
extern void curses_del_wid(winid wid);
|
||||
extern void curs_destroy_all_wins(void);
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
extern void curses_putch(winid wid, int x, int y, int ch,
|
||||
int color, int attrs);
|
||||
struct unicode_representation *u, int color,
|
||||
int attrs);
|
||||
#else
|
||||
extern void curses_putch(winid wid, int x, int y, int ch, int color,
|
||||
int attrs);
|
||||
#endif
|
||||
extern void curses_get_window_size(winid wid, int *height, int *width);
|
||||
extern boolean curses_window_has_border(winid wid);
|
||||
extern boolean curses_window_exists(winid wid);
|
||||
|
||||
@@ -231,8 +231,10 @@ extern
|
||||
* via non-display attribute flag */
|
||||
#define WC2_SUPPRESS_HIST 0x8000L /* 16 putstr(WIN_MESSAGE) supports history
|
||||
* suppression via non-disp attr */
|
||||
#define WC2_MENU_SHIFT 0x010000L /* 17 horizontal menu scrolling */
|
||||
/* 15 free bits */
|
||||
#define WC2_MENU_SHIFT 0x010000L /* 17 horizontal menu scrolling */
|
||||
#define WC2_U_UTF8STR 0x020000L /* 18 utf8str support */
|
||||
#define WC2_U_24BITCOLOR 0x040000L /* 19 24-bit color support available */
|
||||
/* 13 free bits */
|
||||
|
||||
#define ALIGN_LEFT 1
|
||||
#define ALIGN_RIGHT 2
|
||||
|
||||
@@ -78,6 +78,7 @@ struct DisplayDesc {
|
||||
int intr; /* non-zero if inread was interrupted */
|
||||
winid lastwin; /* last window used for I/O */
|
||||
char dismiss_more; /* extra character accepted at --More-- */
|
||||
int topl_utf8; /* non-zero if utf8 in str */
|
||||
};
|
||||
|
||||
#endif /* WINDOW_STRUCTS */
|
||||
@@ -165,6 +166,10 @@ E void term_end_raw_bold(void);
|
||||
E void term_end_color(void);
|
||||
E void term_start_color(int color);
|
||||
#endif /* TEXTCOLOR */
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
extern void term_start_24bitcolor(struct unicode_representation *);
|
||||
extern void term_end_24bitcolor(void); /* termcap.c, consoletty.c */
|
||||
#endif
|
||||
|
||||
/* ### topl.c ### */
|
||||
|
||||
@@ -182,6 +187,11 @@ E void setclipped(void);
|
||||
E void docorner(int, int);
|
||||
E void end_glyphout(void);
|
||||
E void g_putch(int);
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
#if defined(WIN32) || defined(UNIX)
|
||||
E void g_pututf8(uint8 *);
|
||||
#endif
|
||||
#endif /* ENHANCED_SYMBOLS */
|
||||
E void win_tty_init(int);
|
||||
|
||||
/* external declarations */
|
||||
@@ -200,6 +210,7 @@ E void tty_dismiss_nhwindow(winid);
|
||||
E void tty_destroy_nhwindow(winid);
|
||||
E void tty_curs(winid, int, int);
|
||||
E void tty_putstr(winid, int, const char *);
|
||||
E void tty_putmixed(winid window, int attr, const char *str);
|
||||
E void tty_display_file(const char *, boolean);
|
||||
E void tty_start_menu(winid, unsigned long);
|
||||
E void tty_add_menu(winid, const glyph_info *, const ANY_P *, char, char,
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifndef WINTYPE_H
|
||||
#define WINTYPE_H
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
typedef int winid; /* a window identifier */
|
||||
|
||||
/* generic parameter - must not be any larger than a pointer */
|
||||
@@ -60,15 +62,28 @@ typedef struct mi {
|
||||
} menu_item;
|
||||
#define MENU_ITEM_P struct mi
|
||||
|
||||
/* These would be in display.h if they weren't needed to define
|
||||
the windowproc interface for X11 which doesn't seem to include
|
||||
the main NetHack header files */
|
||||
/* These would be in sym.h and display.h if they weren't needed to
|
||||
define the windowproc interface for X11 which doesn't include
|
||||
most of the main NetHack header files */
|
||||
|
||||
typedef struct glyph_map_entry {
|
||||
struct classic_representation {
|
||||
int color;
|
||||
int symidx;
|
||||
};
|
||||
|
||||
struct unicode_representation {
|
||||
uint32 ucolor;
|
||||
uint16 u256coloridx;
|
||||
uint8 *utf8str;
|
||||
};
|
||||
|
||||
typedef struct glyph_map_entry {
|
||||
unsigned glyphflags;
|
||||
struct classic_representation sym;
|
||||
short int tileidx;
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
struct unicode_representation *u;
|
||||
#endif
|
||||
} glyph_map;
|
||||
|
||||
/* glyph plus additional info
|
||||
|
||||
@@ -829,7 +829,10 @@ static const struct early_opt earlyopts[] = {
|
||||
{ARG_SHOWPATHS, "showpaths", 9, FALSE},
|
||||
#ifndef NODUMPENUMS
|
||||
{ARG_DUMPENUMS, "dumpenums", 9, FALSE},
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
{ARG_DUMPGLYPHIDS, "dumpglyphids", 12, FALSE},
|
||||
#endif
|
||||
#endif /* NODUMPENUMS */
|
||||
#ifdef WIN32
|
||||
{ARG_WINDOWS, "windows", 4, TRUE},
|
||||
#endif
|
||||
@@ -913,7 +916,13 @@ argcheck(int argc, char *argv[], enum earlyarg e_arg)
|
||||
dump_enums();
|
||||
return 2;
|
||||
}
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
case ARG_DUMPGLYPHIDS: {
|
||||
dump_glyphids();
|
||||
return 2;
|
||||
}
|
||||
#endif
|
||||
#endif /* NODUMPENUMS */
|
||||
#ifdef WIN32
|
||||
case ARG_WINDOWS: {
|
||||
if (extended_opt) {
|
||||
@@ -1006,6 +1015,17 @@ timet_delta(time_t etim, time_t stim) /* end and start times */
|
||||
}
|
||||
|
||||
#ifndef NODUMPENUMS
|
||||
#define DUMP_ENUMS
|
||||
struct enum_dump monsdump[] = {
|
||||
#include "monsters.h"
|
||||
{ NUMMONS, "NUMMONS" },
|
||||
};
|
||||
struct enum_dump objdump[] = {
|
||||
#include "objects.h"
|
||||
{ NUM_OBJECTS, "NUM_OBJECTS" },
|
||||
};
|
||||
#undef DUMP_ENUMS
|
||||
|
||||
void
|
||||
dump_enums(void)
|
||||
{
|
||||
@@ -1018,21 +1038,6 @@ dump_enums(void)
|
||||
};
|
||||
static const char *const titles[NUM_ENUM_DUMPS] =
|
||||
{ "monnums", "objects_nums" , "misc_object_nums" };
|
||||
struct enum_dump {
|
||||
int val;
|
||||
const char *nm;
|
||||
};
|
||||
|
||||
#define DUMP_ENUMS
|
||||
struct enum_dump monsdump[] = {
|
||||
#include "monsters.h"
|
||||
{ NUMMONS, "NUMMONS" },
|
||||
};
|
||||
struct enum_dump objdump[] = {
|
||||
#include "objects.h"
|
||||
{ NUM_OBJECTS, "NUM_OBJECTS" },
|
||||
};
|
||||
#undef DUMP_ENUMS
|
||||
|
||||
struct enum_dump omdump[] = {
|
||||
{ LAST_GEM, "LAST_GEM" },
|
||||
@@ -1058,6 +1063,14 @@ dump_enums(void)
|
||||
}
|
||||
raw_print("");
|
||||
}
|
||||
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
void
|
||||
dump_glyphids(void)
|
||||
{
|
||||
dump_all_glyphids(stdout);
|
||||
}
|
||||
#endif /* ENHANCED_SYMBOLS */
|
||||
#endif /* NODUMPENUMS */
|
||||
|
||||
/*allmain.c*/
|
||||
|
||||
@@ -373,9 +373,12 @@ const struct instance_globals g_init = {
|
||||
UNDEFINED_VALUES, /* nowhere */
|
||||
UNDEFINED_PTR, /* gate_str */
|
||||
|
||||
/* drawing.c */
|
||||
/* symbols.c */
|
||||
DUMMY, /* symset */
|
||||
0, /* currentgraphics */
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
DUMMY, /* symset_customizations */
|
||||
#endif
|
||||
0, /* currentgraphics */
|
||||
DUMMY, /* showsyms */
|
||||
DUMMY, /* primary_syms */
|
||||
DUMMY, /* rogue_syms */
|
||||
|
||||
147
src/display.c
147
src/display.c
@@ -1363,9 +1363,14 @@ see_traps(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* glyph, ttychar, {color, symidx, glyphflags, tileidx } */
|
||||
/* glyph, ttychar, { glyphflags, { sym.color, sym.symidx },
|
||||
tileidx, u } */
|
||||
static glyph_info no_ginfo = {
|
||||
NO_GLYPH, ' ', { NO_COLOR, 0, MG_BADXY, 0 }
|
||||
NO_GLYPH, ' ', { MG_BADXY, { NO_COLOR, 0 }, 0
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
, 0
|
||||
#endif
|
||||
}
|
||||
};
|
||||
#ifndef UNBUFFERED_GLYPHINFO
|
||||
#define Glyphinfo_at(x, y, glyph) \
|
||||
@@ -1379,12 +1384,17 @@ static glyph_info ginfo;
|
||||
#ifdef USE_TILES
|
||||
extern const glyph_info nul_glyphinfo; /* tile.c */
|
||||
#else
|
||||
/* glyph, ttychar, { color, symidx, glyphflags, tileidx} */
|
||||
/* glyph, ttychar, { glyphflags, { sym.color, sym.symidx },
|
||||
tileidx, 0} */
|
||||
const glyph_info nul_glyphinfo = {
|
||||
NO_GLYPH, ' ',
|
||||
{ /* glyph_map */
|
||||
NO_COLOR, SYM_UNEXPLORED + SYM_OFF_X,
|
||||
MG_UNEXPL, 0
|
||||
MG_UNEXPL,
|
||||
{ NO_COLOR, SYM_UNEXPLORED + SYM_OFF_X },
|
||||
0
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
, 0
|
||||
#endif
|
||||
}
|
||||
};
|
||||
#endif
|
||||
@@ -1393,7 +1403,7 @@ const glyph_info nul_glyphinfo = {
|
||||
extern glyph_map glyphmap[MAX_GLYPH]; /* from tile.c */
|
||||
#else
|
||||
glyph_map glyphmap[MAX_GLYPH] = {
|
||||
{0, 0, 0U, 0 }
|
||||
{ 0U, { 0, 0}, 0, 0 }
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1686,7 +1696,7 @@ show_glyph(int x, int y, int glyph)
|
||||
be thorough and check everything */
|
||||
|| g.gbuf[y][x].glyphinfo.ttychar != glyphinfo.ttychar
|
||||
|| g.gbuf[y][x].glyphinfo.gm.glyphflags != glyphinfo.gm.glyphflags
|
||||
|| g.gbuf[y][x].glyphinfo.gm.color != glyphinfo.gm.color
|
||||
|| g.gbuf[y][x].glyphinfo.gm.sym.color != glyphinfo.gm.sym.color
|
||||
|| g.gbuf[y][x].glyphinfo.gm.tileidx != glyphinfo.gm.tileidx
|
||||
#endif
|
||||
|| iflags.use_background_glyph) {
|
||||
@@ -1721,7 +1731,12 @@ show_glyph(int x, int y, int glyph)
|
||||
static gbuf_entry nul_gbuf = {
|
||||
0, /* gnew */
|
||||
{ GLYPH_UNEXPLORED, (unsigned) ' ', /* glyphinfo.glyph */
|
||||
{ (unsigned) NO_COLOR, 0, MG_UNEXPL, 0 } /* glyphinfo.gm */
|
||||
/* glyphinfo.gm */
|
||||
{ MG_UNEXPL, { (unsigned) NO_COLOR, 0 }, 0
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
, 0
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1743,13 +1758,13 @@ clear_glyph_buffer(void)
|
||||
#endif
|
||||
#ifndef UNBUFFERED_GLYPHINFO
|
||||
nul_gbuf.gnew = (giptr->ttychar != nul_gbuf.glyphinfo.ttychar
|
||||
|| giptr->gm.color != nul_gbuf.glyphinfo.gm.color
|
||||
|| giptr->gm.sym.color != nul_gbuf.glyphinfo.gm.sym.color
|
||||
|| giptr->gm.glyphflags
|
||||
!= nul_gbuf.glyphinfo.gm.glyphflags
|
||||
|| giptr->gm.tileidx != nul_gbuf.glyphinfo.gm.tileidx)
|
||||
#else
|
||||
nul_gbuf.gnew = (giptr->glyphinfo.ttychar != ' '
|
||||
|| giptr->gm.color != NO_COLOR
|
||||
|| giptr->gm.sym.color != NO_COLOR
|
||||
|| (giptr->gm.glyphflags & ~MG_UNEXPL) != 0)
|
||||
#endif
|
||||
? 1 : 0;
|
||||
@@ -1782,12 +1797,12 @@ row_refresh(int start, int stop, int y)
|
||||
#endif
|
||||
#ifndef UNBUFFERED_GLYPHINFO
|
||||
force = (giptr->ttychar != nul_gbuf.glyphinfo.ttychar
|
||||
|| giptr->gm.color != nul_gbuf.glyphinfo.gm.color
|
||||
|| giptr->gm.sym.color != nul_gbuf.glyphinfo.gm.sym.color
|
||||
|| giptr->gm.glyphflags != nul_gbuf.glyphinfo.gm.glyphflags
|
||||
|| giptr->gm.tileidx != nul_gbuf.glyphinfo.gm.tileidx)
|
||||
#else
|
||||
force = (giptr->ttychar != ' '
|
||||
|| giptr->gm.color != NO_COLOR
|
||||
|| giptr->gm.sym.color != NO_COLOR
|
||||
|| (giptr->gm.glyphflags & ~MG_UNEXPL) != 0)
|
||||
#endif
|
||||
? 1 : 0;
|
||||
@@ -2193,7 +2208,7 @@ map_glyphinfo(
|
||||
&& glyph_is_monster(glyph));
|
||||
const glyph_map *gmap = &glyphmap[glyph];
|
||||
|
||||
glyphinfo->gm = *gmap; /* glyphflags, symidx, color, tileidx */
|
||||
glyphinfo->gm = *gmap; /* glyphflags, sym.symidx, sym.color, tileidx */
|
||||
/*
|
||||
* Only hero tinkering permitted on-the-fly (who).
|
||||
* Unique glyphs in glyphmap[] determine everything else (what).
|
||||
@@ -2210,12 +2225,12 @@ map_glyphinfo(
|
||||
} else if (HAS_ROGUE_IBM_GRAPHICS
|
||||
&& g.symset[g.currentgraphics].nocolor == 0) {
|
||||
/* actually player should be yellow-on-gray if in corridor */
|
||||
glyphinfo->gm.color = CLR_YELLOW;
|
||||
glyphinfo->gm.sym.color = CLR_YELLOW;
|
||||
} else if (flags.showrace) {
|
||||
/* for showrace, non-human hero is displayed by the symbol of
|
||||
corresponding type of monster rather than by '@' (handled
|
||||
by newsym()); we change the color to same as human hero */
|
||||
glyphinfo->gm.color = HI_DOMESTIC;
|
||||
glyphinfo->gm.sym.color = HI_DOMESTIC;
|
||||
}
|
||||
#endif
|
||||
/* accessibility
|
||||
@@ -2227,7 +2242,7 @@ map_glyphinfo(
|
||||
if ((g.glyphmap_perlevel_flags & GMAP_ROGUELEVEL)
|
||||
? g.ov_rogue_syms[offset]
|
||||
: g.ov_primary_syms[offset])
|
||||
glyphinfo->gm.symidx = offset;
|
||||
glyphinfo->gm.sym.symidx = offset;
|
||||
}
|
||||
glyphinfo->gm.glyphflags |= MG_HERO;
|
||||
}
|
||||
@@ -2235,9 +2250,9 @@ map_glyphinfo(
|
||||
&& (mgflags & MG_FLAG_NOOVERRIDE) && glyph_is_pet(glyph)) {
|
||||
/* one more accessiblity kludge;
|
||||
turn off override symbol if caller has specfieid NOOVERRIDE */
|
||||
glyphinfo->gm.symidx = mons[glyph_to_mon(glyph)].mlet + SYM_OFF_M;
|
||||
glyphinfo->gm.sym.symidx = mons[glyph_to_mon(glyph)].mlet + SYM_OFF_M;
|
||||
}
|
||||
glyphinfo->ttychar = g.showsyms[glyphinfo->gm.symidx];
|
||||
glyphinfo->ttychar = g.showsyms[glyphinfo->gm.sym.symidx];
|
||||
glyphinfo->glyph = glyph;
|
||||
}
|
||||
|
||||
@@ -2382,38 +2397,38 @@ reset_glyphmap(enum glyphmap_change_triggers trigger)
|
||||
* offsets. The order is set in display.h.
|
||||
*/
|
||||
if ((offset = (glyph - GLYPH_NOTHING_OFF)) >= 0) {
|
||||
gmap->symidx = SYM_NOTHING + SYM_OFF_X;
|
||||
gmap->sym.symidx = SYM_NOTHING + SYM_OFF_X;
|
||||
color = NO_COLOR;
|
||||
gmap->glyphflags |= MG_NOTHING;
|
||||
} else if ((offset = (glyph - GLYPH_UNEXPLORED_OFF)) >= 0) {
|
||||
gmap->symidx = SYM_UNEXPLORED + SYM_OFF_X;
|
||||
gmap->sym.symidx = SYM_UNEXPLORED + SYM_OFF_X;
|
||||
color = NO_COLOR;
|
||||
gmap->glyphflags |= MG_UNEXPL;
|
||||
} else if ((offset = (glyph - GLYPH_STATUE_FEM_PILETOP_OFF)) >= 0) {
|
||||
gmap->symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
if (has_rogue_color)
|
||||
color = CLR_RED;
|
||||
else
|
||||
obj_color(STATUE);
|
||||
gmap->glyphflags |= (MG_STATUE | MG_FEMALE | MG_OBJPILE);
|
||||
} else if ((offset = (glyph - GLYPH_STATUE_MALE_PILETOP_OFF)) >= 0) {
|
||||
gmap->symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
if (has_rogue_color)
|
||||
color = CLR_RED;
|
||||
else
|
||||
obj_color(STATUE);
|
||||
gmap->glyphflags |= (MG_STATUE | MG_MALE | MG_OBJPILE);
|
||||
} else if ((offset = (glyph - GLYPH_BODY_PILETOP_OFF)) >= 0) {
|
||||
gmap->symidx = objects[CORPSE].oc_class + SYM_OFF_O;
|
||||
gmap->sym.symidx = objects[CORPSE].oc_class + SYM_OFF_O;
|
||||
if (has_rogue_color)
|
||||
color = CLR_RED;
|
||||
else
|
||||
mon_color(offset);
|
||||
gmap->glyphflags |= (MG_CORPSE | MG_OBJPILE);
|
||||
} else if ((offset = (glyph - GLYPH_OBJ_PILETOP_OFF)) >= 0) {
|
||||
gmap->symidx = objects[offset].oc_class + SYM_OFF_O;
|
||||
gmap->sym.symidx = objects[offset].oc_class + SYM_OFF_O;
|
||||
if (offset == BOULDER)
|
||||
gmap->symidx = SYM_BOULDER + SYM_OFF_X;
|
||||
gmap->sym.symidx = SYM_BOULDER + SYM_OFF_X;
|
||||
if (has_rogue_color) {
|
||||
switch (objects[offset].oc_class) {
|
||||
case COIN_CLASS:
|
||||
@@ -2430,14 +2445,14 @@ reset_glyphmap(enum glyphmap_change_triggers trigger)
|
||||
obj_color(offset);
|
||||
gmap->glyphflags |= MG_OBJPILE;
|
||||
} else if ((offset = (glyph - GLYPH_STATUE_FEM_OFF)) >= 0) {
|
||||
gmap->symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
if (has_rogue_color)
|
||||
color = CLR_RED;
|
||||
else
|
||||
obj_color(STATUE);
|
||||
gmap->glyphflags |= (MG_STATUE | MG_FEMALE);
|
||||
} else if ((offset = (glyph - GLYPH_STATUE_MALE_OFF)) >= 0) {
|
||||
gmap->symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
if (has_rogue_color)
|
||||
color = CLR_RED;
|
||||
else
|
||||
@@ -2445,70 +2460,70 @@ reset_glyphmap(enum glyphmap_change_triggers trigger)
|
||||
gmap->glyphflags |= (MG_STATUE | MG_MALE);
|
||||
} else if ((offset = (glyph - GLYPH_WARNING_OFF))
|
||||
>= 0) { /* warn flash */
|
||||
gmap->symidx = offset + SYM_OFF_W;
|
||||
gmap->sym.symidx = offset + SYM_OFF_W;
|
||||
if (has_rogue_color)
|
||||
color = NO_COLOR;
|
||||
else
|
||||
warn_color(offset);
|
||||
} else if ((offset = (glyph - GLYPH_EXPLODE_FROSTY_OFF)) >= 0) {
|
||||
gmap->symidx = S_expl_tl + offset + SYM_OFF_P;
|
||||
gmap->sym.symidx = S_expl_tl + offset + SYM_OFF_P;
|
||||
explode_color(expl_frosty);
|
||||
} else if ((offset = (glyph - GLYPH_EXPLODE_FIERY_OFF)) >= 0) {
|
||||
gmap->symidx = S_expl_tl + offset + SYM_OFF_P;
|
||||
gmap->sym.symidx = S_expl_tl + offset + SYM_OFF_P;
|
||||
explode_color(expl_fiery);
|
||||
} else if ((offset = (glyph - GLYPH_EXPLODE_MAGICAL_OFF)) >= 0) {
|
||||
gmap->symidx = S_expl_tl + offset + SYM_OFF_P;
|
||||
gmap->sym.symidx = S_expl_tl + offset + SYM_OFF_P;
|
||||
explode_color(expl_magical);
|
||||
} else if ((offset = (glyph - GLYPH_EXPLODE_WET_OFF)) >= 0) {
|
||||
gmap->symidx = S_expl_tl + offset + SYM_OFF_P;
|
||||
gmap->sym.symidx = S_expl_tl + offset + SYM_OFF_P;
|
||||
explode_color(expl_wet);
|
||||
} else if ((offset = (glyph - GLYPH_EXPLODE_MUDDY_OFF)) >= 0) {
|
||||
gmap->symidx = S_expl_tl + offset + SYM_OFF_P;
|
||||
gmap->sym.symidx = S_expl_tl + offset + SYM_OFF_P;
|
||||
explode_color(expl_muddy);
|
||||
} else if ((offset = (glyph - GLYPH_EXPLODE_NOXIOUS_OFF)) >= 0) {
|
||||
gmap->symidx = S_expl_tl + offset + SYM_OFF_P;
|
||||
gmap->sym.symidx = S_expl_tl + offset + SYM_OFF_P;
|
||||
explode_color(expl_noxious);
|
||||
} else if ((offset = (glyph - GLYPH_EXPLODE_DARK_OFF)) >= 0) {
|
||||
gmap->symidx = S_expl_tl + offset + SYM_OFF_P;
|
||||
gmap->sym.symidx = S_expl_tl + offset + SYM_OFF_P;
|
||||
explode_color(expl_dark);
|
||||
} else if ((offset = (glyph - GLYPH_SWALLOW_OFF)) >= 0) {
|
||||
/* see swallow_to_glyph() in display.c */
|
||||
gmap->symidx = (S_sw_tl + (offset & 0x7)) + SYM_OFF_P;
|
||||
gmap->sym.symidx = (S_sw_tl + (offset & 0x7)) + SYM_OFF_P;
|
||||
if (has_rogue_color)
|
||||
color = NO_COLOR;
|
||||
else
|
||||
mon_color(offset >> 3);
|
||||
} else if ((offset = (glyph - GLYPH_CMAP_C_OFF)) >= 0) {
|
||||
gmap->symidx = S_digbeam + offset + SYM_OFF_P;
|
||||
gmap->sym.symidx = S_digbeam + offset + SYM_OFF_P;
|
||||
if (has_rogue_color)
|
||||
color = cmap_to_roguecolor(S_digbeam + offset);
|
||||
else
|
||||
cmap_color(S_digbeam + offset);
|
||||
} else if ((offset = (glyph - GLYPH_ZAP_OFF)) >= 0) {
|
||||
/* see zapdir_to_glyph() in display.c */
|
||||
gmap->symidx = (S_vbeam + (offset & 0x3)) + SYM_OFF_P;
|
||||
gmap->sym.symidx = (S_vbeam + (offset & 0x3)) + SYM_OFF_P;
|
||||
if (has_rogue_color)
|
||||
color = NO_COLOR;
|
||||
else
|
||||
zap_color((offset >> 2));
|
||||
} else if ((offset = (glyph - GLYPH_CMAP_B_OFF)) >= 0) {
|
||||
int cmap = S_grave + offset;
|
||||
gmap->symidx = cmap + SYM_OFF_P;
|
||||
gmap->sym.symidx = cmap + SYM_OFF_P;
|
||||
cmap_color(cmap);
|
||||
if (!iflags.use_color) {
|
||||
/* try to provide a visible difference between water and lava
|
||||
if they use the same symbol and color is disabled */
|
||||
if (cmap == S_lava
|
||||
&& (g.showsyms[gmap->symidx]
|
||||
&& (g.showsyms[gmap->sym.symidx]
|
||||
== g.showsyms[S_pool + SYM_OFF_P]
|
||||
|| g.showsyms[gmap->symidx]
|
||||
|| g.showsyms[gmap->sym.symidx]
|
||||
== g.showsyms[S_water + SYM_OFF_P])) {
|
||||
gmap->glyphflags |= MG_BW_LAVA;
|
||||
/* similar for floor [what about empty doorway?] and ice */
|
||||
} else if (offset == S_ice
|
||||
&& (g.showsyms[gmap->symidx]
|
||||
&& (g.showsyms[gmap->sym.symidx]
|
||||
== g.showsyms[S_room + SYM_OFF_P]
|
||||
|| g.showsyms[gmap->symidx]
|
||||
|| g.showsyms[gmap->sym.symidx]
|
||||
== g.showsyms[S_darkroom
|
||||
+ SYM_OFF_P])) {
|
||||
gmap->glyphflags |= MG_BW_ICE;
|
||||
@@ -2518,14 +2533,14 @@ reset_glyphmap(enum glyphmap_change_triggers trigger)
|
||||
}
|
||||
} else if ((offset = (glyph - GLYPH_ALTAR_OFF)) >= 0) {
|
||||
/* unaligned, chaotic, neutral, lawful, other altar */
|
||||
gmap->symidx = S_altar + SYM_OFF_P;
|
||||
gmap->sym.symidx = S_altar + SYM_OFF_P;
|
||||
if (has_rogue_color)
|
||||
color = cmap_to_roguecolor(S_altar);
|
||||
else
|
||||
altar_color(offset);
|
||||
} else if ((offset = (glyph - GLYPH_CMAP_A_OFF)) >= 0) {
|
||||
int cmap = S_ndoor + offset;
|
||||
gmap->symidx = cmap + SYM_OFF_P;
|
||||
gmap->sym.symidx = cmap + SYM_OFF_P;
|
||||
cmap_color(cmap);
|
||||
/*
|
||||
* Some speciality color mappings not hardcoded in data init
|
||||
@@ -2536,36 +2551,36 @@ reset_glyphmap(enum glyphmap_change_triggers trigger)
|
||||
/* provide a visible difference if normal and lit corridor
|
||||
use the same symbol */
|
||||
} else if ((cmap == S_litcorr)
|
||||
&& g.showsyms[gmap->symidx]
|
||||
&& g.showsyms[gmap->sym.symidx]
|
||||
== g.showsyms[S_corr + SYM_OFF_P]) {
|
||||
color = CLR_WHITE;
|
||||
#endif
|
||||
}
|
||||
} else if ((offset = (glyph - GLYPH_CMAP_SOKO_OFF)) >= 0) {
|
||||
gmap->symidx = S_vwall + offset + SYM_OFF_P;
|
||||
gmap->sym.symidx = S_vwall + offset + SYM_OFF_P;
|
||||
wall_color(sokoban_walls);
|
||||
} else if ((offset = (glyph - GLYPH_CMAP_KNOX_OFF)) >= 0) {
|
||||
gmap->symidx = S_vwall + offset + SYM_OFF_P;
|
||||
gmap->sym.symidx = S_vwall + offset + SYM_OFF_P;
|
||||
wall_color(knox_walls);
|
||||
} else if ((offset = (glyph - GLYPH_CMAP_GEH_OFF)) >= 0) {
|
||||
gmap->symidx = S_vwall + offset + SYM_OFF_P;
|
||||
gmap->sym.symidx = S_vwall + offset + SYM_OFF_P;
|
||||
wall_color(gehennom_walls);
|
||||
} else if ((offset = (glyph - GLYPH_CMAP_MINES_OFF)) >= 0) {
|
||||
gmap->symidx = S_vwall + offset + SYM_OFF_P;
|
||||
gmap->sym.symidx = S_vwall + offset + SYM_OFF_P;
|
||||
wall_color(mines_walls);
|
||||
} else if ((offset = (glyph - GLYPH_CMAP_MAIN_OFF)) >= 0) {
|
||||
gmap->symidx = S_vwall + offset + SYM_OFF_P;
|
||||
gmap->sym.symidx = S_vwall + offset + SYM_OFF_P;
|
||||
if (has_rogue_color)
|
||||
color = cmap_to_roguecolor(S_vwall + offset);
|
||||
else
|
||||
wall_color(main_walls);
|
||||
} else if ((offset = (glyph - GLYPH_CMAP_STONE_OFF)) >= 0) {
|
||||
gmap->symidx = SYM_OFF_P;
|
||||
gmap->sym.symidx = SYM_OFF_P;
|
||||
cmap_color(S_stone);
|
||||
} else if ((offset = (glyph - GLYPH_OBJ_OFF)) >= 0) {
|
||||
gmap->symidx = objects[offset].oc_class + SYM_OFF_O;
|
||||
gmap->sym.symidx = objects[offset].oc_class + SYM_OFF_O;
|
||||
if (offset == BOULDER)
|
||||
gmap->symidx = SYM_BOULDER + SYM_OFF_X;
|
||||
gmap->sym.symidx = SYM_BOULDER + SYM_OFF_X;
|
||||
if (has_rogue_color) {
|
||||
switch (objects[offset].oc_class) {
|
||||
case COIN_CLASS:
|
||||
@@ -2581,7 +2596,7 @@ reset_glyphmap(enum glyphmap_change_triggers trigger)
|
||||
} else
|
||||
obj_color(offset);
|
||||
} else if ((offset = (glyph - GLYPH_RIDDEN_FEM_OFF)) >= 0) {
|
||||
gmap->symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
if (has_rogue_color)
|
||||
/* This currently implies that the hero is here -- monsters */
|
||||
/* don't ride (yet...). Should we set it to yellow like in */
|
||||
@@ -2592,21 +2607,21 @@ reset_glyphmap(enum glyphmap_change_triggers trigger)
|
||||
mon_color(offset);
|
||||
gmap->glyphflags |= (MG_RIDDEN | MG_FEMALE);
|
||||
} else if ((offset = (glyph - GLYPH_RIDDEN_MALE_OFF)) >= 0) {
|
||||
gmap->symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
if (has_rogue_color)
|
||||
color = NO_COLOR;
|
||||
else
|
||||
mon_color(offset);
|
||||
gmap->glyphflags |= (MG_RIDDEN | MG_MALE);
|
||||
} else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) {
|
||||
gmap->symidx = objects[CORPSE].oc_class + SYM_OFF_O;
|
||||
gmap->sym.symidx = objects[CORPSE].oc_class + SYM_OFF_O;
|
||||
if (has_rogue_color)
|
||||
color = CLR_RED;
|
||||
else
|
||||
mon_color(offset);
|
||||
gmap->glyphflags |= MG_CORPSE;
|
||||
} else if ((offset = (glyph - GLYPH_DETECT_FEM_OFF)) >= 0) {
|
||||
gmap->symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
if (has_rogue_color)
|
||||
color = NO_COLOR;
|
||||
else
|
||||
@@ -2615,7 +2630,7 @@ reset_glyphmap(enum glyphmap_change_triggers trigger)
|
||||
/* is_reverse = TRUE; */
|
||||
gmap->glyphflags |= (MG_DETECT | MG_FEMALE);
|
||||
} else if ((offset = (glyph - GLYPH_DETECT_MALE_OFF)) >= 0) {
|
||||
gmap->symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
if (has_rogue_color)
|
||||
color = NO_COLOR;
|
||||
else
|
||||
@@ -2624,28 +2639,28 @@ reset_glyphmap(enum glyphmap_change_triggers trigger)
|
||||
/* is_reverse = TRUE; */
|
||||
gmap->glyphflags |= (MG_DETECT | MG_MALE);
|
||||
} else if ((offset = (glyph - GLYPH_INVIS_OFF)) >= 0) {
|
||||
gmap->symidx = SYM_INVISIBLE + SYM_OFF_X;
|
||||
gmap->sym.symidx = SYM_INVISIBLE + SYM_OFF_X;
|
||||
if (has_rogue_color)
|
||||
color = NO_COLOR;
|
||||
else
|
||||
invis_color(offset);
|
||||
gmap->glyphflags |= MG_INVIS;
|
||||
} else if ((offset = (glyph - GLYPH_PET_FEM_OFF)) >= 0) {
|
||||
gmap->symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
if (has_rogue_color)
|
||||
color = NO_COLOR;
|
||||
else
|
||||
pet_color(offset);
|
||||
gmap->glyphflags |= (MG_PET | MG_FEMALE);
|
||||
} else if ((offset = (glyph - GLYPH_PET_MALE_OFF)) >= 0) {
|
||||
gmap->symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
if (has_rogue_color)
|
||||
color = NO_COLOR;
|
||||
else
|
||||
pet_color(offset);
|
||||
gmap->glyphflags |= (MG_PET | MG_MALE);
|
||||
} else if ((offset = (glyph - GLYPH_MON_FEM_OFF)) >= 0) {
|
||||
gmap->symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
if (has_rogue_color) {
|
||||
color = NO_COLOR;
|
||||
} else {
|
||||
@@ -2653,7 +2668,7 @@ reset_glyphmap(enum glyphmap_change_triggers trigger)
|
||||
}
|
||||
gmap->glyphflags |= MG_FEMALE;
|
||||
} else if ((offset = (glyph - GLYPH_MON_MALE_OFF)) >= 0) {
|
||||
gmap->symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
gmap->sym.symidx = mons[offset].mlet + SYM_OFF_M;
|
||||
if (has_rogue_color) {
|
||||
color = CLR_YELLOW;
|
||||
} else {
|
||||
@@ -2669,7 +2684,7 @@ reset_glyphmap(enum glyphmap_change_triggers trigger)
|
||||
: g.ov_primary_syms[SYM_PET_OVERRIDE + SYM_OFF_X]);
|
||||
|
||||
if (g.showsyms[pet_override] != ' ')
|
||||
gmap->symidx = SYM_PET_OVERRIDE + SYM_OFF_X;
|
||||
gmap->sym.symidx = SYM_PET_OVERRIDE + SYM_OFF_X;
|
||||
}
|
||||
#ifdef TEXTCOLOR
|
||||
/* Turn off color if no color defined, or rogue level w/o PC graphics.
|
||||
@@ -2679,7 +2694,7 @@ reset_glyphmap(enum glyphmap_change_triggers trigger)
|
||||
&& !has_rogue_color)) || !iflags.use_color)
|
||||
#endif
|
||||
color = NO_COLOR;
|
||||
gmap->color = color;
|
||||
gmap->sym.color = color;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
src/do.c
2
src/do.c
@@ -1455,7 +1455,7 @@ goto_level(
|
||||
}
|
||||
|
||||
if (Is_rogue_level(newlevel) || Is_rogue_level(&u.uz))
|
||||
assign_graphics(Is_rogue_level(newlevel) ? ROGUESET : PRIMARY);
|
||||
assign_graphics(Is_rogue_level(newlevel) ? ROGUESET : PRIMARYSET);
|
||||
check_gold_symbol();
|
||||
/* record this level transition as a potential seen branch unless using
|
||||
* some non-standard means of transportation (level teleport).
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "color.h"
|
||||
#include "rm.h"
|
||||
#include "objclass.h"
|
||||
#include "wintype.h"
|
||||
#include "sym.h"
|
||||
|
||||
/* Relevant header information in rm.h, objclass.h, sym.h, defsym.h. */
|
||||
|
||||
214
src/files.c
214
src/files.c
@@ -165,8 +165,6 @@ static void wizkit_addinv(struct obj *);
|
||||
boolean proc_wizkit_line(char *buf);
|
||||
void read_wizkit(void);
|
||||
static FILE *fopen_sym_file(void);
|
||||
boolean proc_symset_line(char *);
|
||||
static void set_symhandling(char *, int);
|
||||
|
||||
#ifdef SELF_RECOVER
|
||||
static boolean copy_bytes(int, int);
|
||||
@@ -2678,7 +2676,7 @@ parse_config_line(char *origbuf)
|
||||
}
|
||||
switch_symbols(TRUE);
|
||||
} else if (match_varname(buf, "SYMBOLS", 4)) {
|
||||
if (!parsesymbols(bufp, PRIMARY)) {
|
||||
if (!parsesymbols(bufp, PRIMARYSET)) {
|
||||
config_error_add("Error in SYMBOLS definition '%s'", bufp);
|
||||
retval = FALSE;
|
||||
}
|
||||
@@ -3443,7 +3441,7 @@ fopen_sym_file(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if the chose symset was found and loaded.
|
||||
* Returns 1 if the chosen symset was found and loaded.
|
||||
* 0 if it wasn't found in the sym file or other problem.
|
||||
*/
|
||||
int
|
||||
@@ -3492,214 +3490,6 @@ read_sym_file(int which_set)
|
||||
return 1;
|
||||
}
|
||||
|
||||
boolean
|
||||
proc_symset_line(char *buf)
|
||||
{
|
||||
return !((boolean) parse_sym_line(buf, g.symset_which_set));
|
||||
}
|
||||
|
||||
/* returns 0 on error */
|
||||
int
|
||||
parse_sym_line(char *buf, int which_set)
|
||||
{
|
||||
int val, i;
|
||||
struct symparse *symp;
|
||||
char *bufp, *commentp, *altp;
|
||||
|
||||
if (strlen(buf) >= BUFSZ)
|
||||
buf[BUFSZ - 1] = '\0';
|
||||
/* convert each instance of whitespace (tabs, consecutive spaces)
|
||||
into a single space; leading and trailing spaces are stripped */
|
||||
mungspaces(buf);
|
||||
|
||||
/* remove trailing comment, if any (this isn't strictly needed for
|
||||
individual symbols, and it won't matter if "X#comment" without
|
||||
separating space slips through; for handling or set description,
|
||||
symbol set creator is responsible for preceding '#' with a space
|
||||
and that comment itself doesn't contain " #") */
|
||||
if ((commentp = rindex(buf, '#')) != 0 && commentp[-1] == ' ')
|
||||
commentp[-1] = '\0';
|
||||
|
||||
/* find the '=' or ':' */
|
||||
bufp = index(buf, '=');
|
||||
altp = index(buf, ':');
|
||||
if (!bufp || (altp && altp < bufp))
|
||||
bufp = altp;
|
||||
if (!bufp) {
|
||||
if (strncmpi(buf, "finish", 6) == 0) {
|
||||
/* end current graphics set */
|
||||
if (g.chosen_symset_start)
|
||||
g.chosen_symset_end = TRUE;
|
||||
g.chosen_symset_start = FALSE;
|
||||
return 1;
|
||||
}
|
||||
config_error_add("No \"finish\"");
|
||||
return 0;
|
||||
}
|
||||
/* skip '=' and space which follows, if any */
|
||||
++bufp;
|
||||
if (*bufp == ' ')
|
||||
++bufp;
|
||||
|
||||
symp = match_sym(buf);
|
||||
if (!symp) {
|
||||
config_error_add("Unknown sym keyword");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!g.symset[which_set].name) {
|
||||
/* A null symset name indicates that we're just
|
||||
building a pick-list of possible symset
|
||||
values from the file, so only do that */
|
||||
if (symp->range == SYM_CONTROL) {
|
||||
struct symsetentry *tmpsp, *lastsp;
|
||||
|
||||
for (lastsp = g.symset_list; lastsp; lastsp = lastsp->next)
|
||||
if (!lastsp->next)
|
||||
break;
|
||||
switch (symp->idx) {
|
||||
case 0:
|
||||
tmpsp = (struct symsetentry *) alloc(sizeof *tmpsp);
|
||||
tmpsp->next = (struct symsetentry *) 0;
|
||||
if (!lastsp)
|
||||
g.symset_list = tmpsp;
|
||||
else
|
||||
lastsp->next = tmpsp;
|
||||
tmpsp->idx = g.symset_count++;
|
||||
tmpsp->name = dupstr(bufp);
|
||||
tmpsp->desc = (char *) 0;
|
||||
tmpsp->handling = H_UNK;
|
||||
/* initialize restriction bits */
|
||||
tmpsp->nocolor = 0;
|
||||
tmpsp->primary = 0;
|
||||
tmpsp->rogue = 0;
|
||||
break;
|
||||
case 2:
|
||||
/* handler type identified */
|
||||
tmpsp = lastsp; /* most recent symset */
|
||||
for (i = 0; known_handling[i]; ++i)
|
||||
if (!strcmpi(known_handling[i], bufp)) {
|
||||
tmpsp->handling = i;
|
||||
break; /* for loop */
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
/* description:something */
|
||||
tmpsp = lastsp; /* most recent symset */
|
||||
if (tmpsp && !tmpsp->desc)
|
||||
tmpsp->desc = dupstr(bufp);
|
||||
break;
|
||||
case 5:
|
||||
/* restrictions: xxxx*/
|
||||
tmpsp = lastsp; /* most recent symset */
|
||||
for (i = 0; known_restrictions[i]; ++i) {
|
||||
if (!strcmpi(known_restrictions[i], bufp)) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
tmpsp->primary = 1;
|
||||
break;
|
||||
case 1:
|
||||
tmpsp->rogue = 1;
|
||||
break;
|
||||
}
|
||||
break; /* while loop */
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (symp->range) {
|
||||
if (symp->range == SYM_CONTROL) {
|
||||
switch (symp->idx) {
|
||||
case 0:
|
||||
/* start of symset */
|
||||
if (!strcmpi(bufp, g.symset[which_set].name)) {
|
||||
/* matches desired one */
|
||||
g.chosen_symset_start = TRUE;
|
||||
/* these init_*() functions clear symset fields too */
|
||||
if (which_set == ROGUESET)
|
||||
init_rogue_symbols();
|
||||
else if (which_set == PRIMARY)
|
||||
init_primary_symbols();
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* finish symset */
|
||||
if (g.chosen_symset_start)
|
||||
g.chosen_symset_end = TRUE;
|
||||
g.chosen_symset_start = FALSE;
|
||||
break;
|
||||
case 2:
|
||||
/* handler type identified */
|
||||
if (g.chosen_symset_start)
|
||||
set_symhandling(bufp, which_set);
|
||||
break;
|
||||
/* case 3: (description) is ignored here */
|
||||
case 4: /* color:off */
|
||||
if (g.chosen_symset_start) {
|
||||
if (bufp) {
|
||||
if (!strcmpi(bufp, "true") || !strcmpi(bufp, "yes")
|
||||
|| !strcmpi(bufp, "on"))
|
||||
g.symset[which_set].nocolor = 0;
|
||||
else if (!strcmpi(bufp, "false")
|
||||
|| !strcmpi(bufp, "no")
|
||||
|| !strcmpi(bufp, "off"))
|
||||
g.symset[which_set].nocolor = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5: /* restrictions: xxxx*/
|
||||
if (g.chosen_symset_start) {
|
||||
int n = 0;
|
||||
|
||||
while (known_restrictions[n]) {
|
||||
if (!strcmpi(known_restrictions[n], bufp)) {
|
||||
switch (n) {
|
||||
case 0:
|
||||
g.symset[which_set].primary = 1;
|
||||
break;
|
||||
case 1:
|
||||
g.symset[which_set].rogue = 1;
|
||||
break;
|
||||
}
|
||||
break; /* while loop */
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else { /* !SYM_CONTROL */
|
||||
val = sym_val(bufp);
|
||||
if (g.chosen_symset_start) {
|
||||
if (which_set == PRIMARY) {
|
||||
update_primary_symset(symp, val);
|
||||
} else if (which_set == ROGUESET) {
|
||||
update_rogue_symset(symp, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
set_symhandling(char *handling, int which_set)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
g.symset[which_set].handling = H_UNK;
|
||||
while (known_handling[i]) {
|
||||
if (!strcmpi(known_handling[i], handling)) {
|
||||
g.symset[which_set].handling = i;
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------- END SYMSET FILE HANDLING ----------- */
|
||||
|
||||
/* ---------- BEGIN SCOREBOARD CREATION ----------- */
|
||||
|
||||
@@ -1378,4 +1378,49 @@ FITSuint_(unsigned long long i, const char *file, int line){
|
||||
return (unsigned)i;
|
||||
}
|
||||
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
|
||||
/* Unicode routines */
|
||||
|
||||
int
|
||||
unicodeval_to_utf8str(int uval, uint8 *buffer, size_t bufsz)
|
||||
{
|
||||
// static uint8 buffer[7];
|
||||
uint8 *b = buffer;
|
||||
|
||||
if (bufsz < 5)
|
||||
return 0;
|
||||
/*
|
||||
* Binary Hex Comments
|
||||
* 0xxxxxxx 0x00..0x7F Only byte of a 1-byte character encoding
|
||||
* 10xxxxxx 0x80..0xBF Continuation byte : one of 1-3 bytes following
|
||||
* first 110xxxxx 0xC0..0xDF First byte of a 2-byte character encoding
|
||||
* 1110xxxx 0xE0..0xEF First byte of a 3-byte character encoding
|
||||
* 11110xxx 0xF0..0xF7 First byte of a 4-byte character encoding
|
||||
*/
|
||||
*b = '\0';
|
||||
if (uval < 0x80) {
|
||||
*b++ = uval;
|
||||
} else if (uval < 0x800) {
|
||||
*b++ = 192 + uval / 64;
|
||||
*b++ = 128 + uval % 64;
|
||||
} else if (uval - 0xd800u < 0x800) {
|
||||
return 0;
|
||||
} else if (uval < 0x10000) {
|
||||
*b++ = 224 + uval / 4096;
|
||||
*b++ = 128 + uval / 64 % 64;
|
||||
*b++ = 128 + uval % 64;
|
||||
} else if (uval < 0x110000) {
|
||||
*b++ = 240 + uval / 262144;
|
||||
*b++ = 128 + uval / 4096 % 64;
|
||||
*b++ = 128 + uval / 64 % 64;
|
||||
*b++ = 128 + uval % 64;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
*b = '\0'; /* NUL terminate */
|
||||
return 1;
|
||||
}
|
||||
#endif /* ENHANCED_SYMBOLS */
|
||||
|
||||
/*hacklib.c*/
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "config.h"
|
||||
#include "permonst.h"
|
||||
#include "objclass.h"
|
||||
#include "wintype.h"
|
||||
#include "sym.h"
|
||||
#include "artilist.h"
|
||||
#include "dungeon.h"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "permonst.h"
|
||||
#include "wintype.h"
|
||||
#include "sym.h"
|
||||
|
||||
#ifdef C
|
||||
|
||||
444
src/options.c
444
src/options.c
@@ -505,7 +505,7 @@ parseoptions(register char *opts, boolean tinitial, boolean tfrom_file)
|
||||
|
||||
if (!got_match) {
|
||||
/* Is it a symbol? */
|
||||
if (strstr(opts, "S_") == opts && parsesymbols(opts, PRIMARY)) {
|
||||
if (strstr(opts, "S_") == opts && parsesymbols(opts, PRIMARYSET)) {
|
||||
switch_symbols(TRUE);
|
||||
check_gold_symbol();
|
||||
optresult = optn_ok;
|
||||
@@ -872,7 +872,7 @@ optfn_boulder(int optidx UNUSED, int req, boolean negated UNUSED,
|
||||
if (!g.opt_initial) {
|
||||
nhsym sym = get_othersym(SYM_BOULDER,
|
||||
Is_rogue_level(&u.uz) ? ROGUESET
|
||||
: PRIMARY);
|
||||
: PRIMARYSET);
|
||||
|
||||
if (sym)
|
||||
g.showsyms[SYM_BOULDER + SYM_OFF_X] = sym;
|
||||
@@ -946,13 +946,13 @@ optfn_cursesgraphics(int optidx, int req, boolean negated,
|
||||
#ifdef BACKWARD_COMPAT
|
||||
if (!negated) {
|
||||
/* There is no rogue level cursesgraphics-specific set */
|
||||
if (g.symset[PRIMARY].name) {
|
||||
if (g.symset[PRIMARYSET].name) {
|
||||
badflag = TRUE;
|
||||
} else {
|
||||
g.symset[PRIMARY].name = dupstr(allopt[optidx].name);
|
||||
if (!read_sym_file(PRIMARY)) {
|
||||
g.symset[PRIMARYSET].name = dupstr(allopt[optidx].name);
|
||||
if (!read_sym_file(PRIMARYSET)) {
|
||||
badflag = TRUE;
|
||||
clear_symsetentry(PRIMARY, TRUE);
|
||||
clear_symsetentry(PRIMARYSET, TRUE);
|
||||
} else
|
||||
switch_symbols(TRUE);
|
||||
}
|
||||
@@ -996,13 +996,13 @@ optfn_DECgraphics(int optidx, int req, boolean negated,
|
||||
#ifdef BACKWARD_COMPAT
|
||||
if (!negated) {
|
||||
/* There is no rogue level DECgraphics-specific set */
|
||||
if (g.symset[PRIMARY].name) {
|
||||
if (g.symset[PRIMARYSET].name) {
|
||||
badflag = TRUE;
|
||||
} else {
|
||||
g.symset[PRIMARY].name = dupstr(allopt[optidx].name);
|
||||
if (!read_sym_file(PRIMARY)) {
|
||||
g.symset[PRIMARYSET].name = dupstr(allopt[optidx].name);
|
||||
if (!read_sym_file(PRIMARYSET)) {
|
||||
badflag = TRUE;
|
||||
clear_symsetentry(PRIMARY, TRUE);
|
||||
clear_symsetentry(PRIMARYSET, TRUE);
|
||||
} else
|
||||
switch_symbols(TRUE);
|
||||
}
|
||||
@@ -1390,6 +1390,43 @@ optfn_gender(int optidx, int req, boolean negated, char *opts, char *op)
|
||||
return optn_ok;
|
||||
}
|
||||
|
||||
static int
|
||||
optfn_glyph(int optidx UNUSED, int req, boolean negated, char *opts, char *op)
|
||||
{
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
int glyph;
|
||||
#endif
|
||||
|
||||
if (req == do_init) {
|
||||
return optn_ok;
|
||||
}
|
||||
if (req == do_set) {
|
||||
/* OPTION=glyph:G_glyph/U+NNNN/r-g-b */
|
||||
if (negated) {
|
||||
if (op != empty_optstr) {
|
||||
bad_negation("glyph", TRUE);
|
||||
return optn_err;
|
||||
}
|
||||
}
|
||||
if (op == empty_optstr)
|
||||
return optn_err;
|
||||
/* strip leading/trailing spaces, condense internal ones (3.6.2) */
|
||||
mungspaces(op);
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if (!glyphrep_to_custom_map_entries(op, &glyph))
|
||||
return optn_err;
|
||||
#endif
|
||||
return optn_ok;
|
||||
}
|
||||
if (req == get_val) {
|
||||
if (!opts)
|
||||
return optn_err;
|
||||
Sprintf(opts, "%s", to_be_done);
|
||||
return optn_ok;
|
||||
}
|
||||
return optn_ok;
|
||||
}
|
||||
|
||||
static int
|
||||
optfn_hilite_status(
|
||||
int optidx UNUSED,
|
||||
@@ -1534,13 +1571,13 @@ optfn_MACgraphics(int optidx, int req, boolean negated, char *opts, char *op)
|
||||
if (req == do_set) {
|
||||
/* "MACgraphics" */
|
||||
if (!negated) {
|
||||
if (g.symset[PRIMARY].name) {
|
||||
if (g.symset[PRIMARYSET].name) {
|
||||
badflag = TRUE;
|
||||
} else {
|
||||
g.symset[PRIMARY].name = dupstr(allopt[optidx].name);
|
||||
if (!read_sym_file(PRIMARY)) {
|
||||
g.symset[PRIMARYSET].name = dupstr(allopt[optidx].name);
|
||||
if (!read_sym_file(PRIMARYSET)) {
|
||||
badflag = TRUE;
|
||||
clear_symsetentry(PRIMARY, TRUE);
|
||||
clear_symsetentry(PRIMARYSET, TRUE);
|
||||
}
|
||||
}
|
||||
if (badflag) {
|
||||
@@ -3303,25 +3340,37 @@ optfn_suppress_alert(int optidx, int req, boolean negated,
|
||||
return optn_ok;
|
||||
}
|
||||
|
||||
extern const char *known_handling[]; /* symbols.c */
|
||||
extern const char *known_restrictions[]; /* symbols.c */
|
||||
|
||||
static int
|
||||
optfn_symset(int optidx UNUSED, int req, boolean negated UNUSED,
|
||||
char *opts, char *op)
|
||||
optfn_symset(int optidx UNUSED, int req, boolean negated UNUSED, char *opts,
|
||||
char *op)
|
||||
{
|
||||
if (req == do_init) {
|
||||
return optn_ok;
|
||||
}
|
||||
if (req == do_set) {
|
||||
if (op != empty_optstr) {
|
||||
g.symset[PRIMARY].name = dupstr(op);
|
||||
if (!read_sym_file(PRIMARY)) {
|
||||
clear_symsetentry(PRIMARY, TRUE);
|
||||
g.symset[PRIMARYSET].name = dupstr(op);
|
||||
if (!read_sym_file(PRIMARYSET)) {
|
||||
clear_symsetentry(PRIMARYSET, TRUE);
|
||||
config_error_add(
|
||||
"Unable to load symbol set \"%s\" from \"%s\"", op,
|
||||
SYMBOLS);
|
||||
return optn_err;
|
||||
} else {
|
||||
switch_symbols(g.symset[PRIMARY].name != (char *) 0);
|
||||
g.opt_need_redraw = TRUE;
|
||||
if (g.symset[PRIMARYSET].handling) {
|
||||
#ifndef ENHANCED_SYMBOLS
|
||||
if (g.symset[PRIMARYSET].handling == H_UTF8) {
|
||||
config_error_add("Unavailable symset handler \"%s\" for %s",
|
||||
known_handling[H_UTF8], op);
|
||||
load_symset("default", PRIMARYSET);
|
||||
}
|
||||
#endif
|
||||
switch_symbols(g.symset[PRIMARYSET].name != (char *) 0);
|
||||
g.opt_need_redraw = g.opt_need_glyph_reset = TRUE;
|
||||
}
|
||||
}
|
||||
} else
|
||||
return optn_err;
|
||||
@@ -3331,13 +3380,32 @@ optfn_symset(int optidx UNUSED, int req, boolean negated UNUSED,
|
||||
if (!opts)
|
||||
return optn_err;
|
||||
Sprintf(opts, "%s",
|
||||
g.symset[PRIMARY].name ? g.symset[PRIMARY].name : "default");
|
||||
if (g.currentgraphics == PRIMARY && g.symset[PRIMARY].name)
|
||||
g.symset[PRIMARYSET].name ? g.symset[PRIMARYSET].name : "default");
|
||||
if (g.currentgraphics == PRIMARYSET && g.symset[PRIMARYSET].name)
|
||||
Strcat(opts, ", active");
|
||||
if (g.symset[PRIMARYSET].handling) {
|
||||
Sprintf(eos(opts), ", handler=%s",
|
||||
known_handling[g.symset[PRIMARYSET].handling]);
|
||||
}
|
||||
return optn_ok;
|
||||
}
|
||||
if (req == do_handler) {
|
||||
return handler_symset(optidx);
|
||||
int reslt;
|
||||
|
||||
if (g.symset[PRIMARYSET].handling == H_UTF8) {
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if (!glyphid_cache_status())
|
||||
fill_glyphid_cache();
|
||||
#endif
|
||||
}
|
||||
reslt = handler_symset(optidx);
|
||||
if (g.symset[PRIMARYSET].handling == H_UTF8) {
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if (glyphid_cache_status())
|
||||
free_glyphid_cache();
|
||||
#endif
|
||||
}
|
||||
return reslt;
|
||||
}
|
||||
return optn_ok;
|
||||
}
|
||||
@@ -5082,187 +5150,16 @@ handler_whatis_filter(void)
|
||||
return optn_ok;
|
||||
}
|
||||
|
||||
DISABLE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
static int
|
||||
handler_symset(int optidx)
|
||||
{
|
||||
winid tmpwin;
|
||||
anything any;
|
||||
int n;
|
||||
char buf[BUFSZ];
|
||||
menu_item *symset_pick = (menu_item *) 0;
|
||||
boolean rogueflag = (optidx == opt_roguesymset),
|
||||
ready_to_switch = FALSE,
|
||||
nothing_to_do = FALSE;
|
||||
char *symset_name, fmtstr[20];
|
||||
struct symsetentry *sl;
|
||||
int res, which_set, setcount = 0, chosen = -2, defindx = 0;
|
||||
int reslt;
|
||||
|
||||
which_set = rogueflag ? ROGUESET : PRIMARY;
|
||||
g.symset_list = (struct symsetentry *) 0;
|
||||
/* clear symset[].name as a flag to read_sym_file() to build list */
|
||||
symset_name = g.symset[which_set].name;
|
||||
g.symset[which_set].name = (char *) 0;
|
||||
|
||||
res = read_sym_file(which_set);
|
||||
/* put symset name back */
|
||||
g.symset[which_set].name = symset_name;
|
||||
|
||||
if (res && g.symset_list) {
|
||||
int thissize,
|
||||
biggest = (int) (sizeof "Default Symbols" - sizeof ""),
|
||||
big_desc = 0;
|
||||
|
||||
for (sl = g.symset_list; sl; sl = sl->next) {
|
||||
/* check restrictions */
|
||||
if (rogueflag ? sl->primary : sl->rogue)
|
||||
continue;
|
||||
#ifndef MAC_GRAPHICS_ENV
|
||||
if (sl->handling == H_MAC)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
setcount++;
|
||||
/* find biggest name */
|
||||
thissize = sl->name ? (int) strlen(sl->name) : 0;
|
||||
if (thissize > biggest)
|
||||
biggest = thissize;
|
||||
thissize = sl->desc ? (int) strlen(sl->desc) : 0;
|
||||
if (thissize > big_desc)
|
||||
big_desc = thissize;
|
||||
}
|
||||
if (!setcount) {
|
||||
pline("There are no appropriate %s symbol sets available.",
|
||||
rogueflag ? "rogue level" : "primary");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Sprintf(fmtstr, "%%-%ds %%s", biggest + 2);
|
||||
tmpwin = create_nhwindow(NHW_MENU);
|
||||
start_menu(tmpwin, MENU_BEHAVE_STANDARD);
|
||||
any = cg.zeroany;
|
||||
any.a_int = 1; /* -1 + 2 [see 'if (sl->name) {' below]*/
|
||||
if (!symset_name)
|
||||
defindx = any.a_int;
|
||||
add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0, ATR_NONE,
|
||||
"Default Symbols",
|
||||
(any.a_int == defindx) ? MENU_ITEMFLAGS_SELECTED
|
||||
: MENU_ITEMFLAGS_NONE);
|
||||
|
||||
for (sl = g.symset_list; sl; sl = sl->next) {
|
||||
/* check restrictions */
|
||||
if (rogueflag ? sl->primary : sl->rogue)
|
||||
continue;
|
||||
#ifndef MAC_GRAPHICS_ENV
|
||||
if (sl->handling == H_MAC)
|
||||
continue;
|
||||
#endif
|
||||
if (sl->name) {
|
||||
/* +2: sl->idx runs from 0 to N-1 for N symsets;
|
||||
+1 because Defaults are implicitly in slot [0];
|
||||
+1 again so that valid data is never 0 */
|
||||
any.a_int = sl->idx + 2;
|
||||
if (symset_name && !strcmpi(sl->name, symset_name))
|
||||
defindx = any.a_int;
|
||||
Sprintf(buf, fmtstr, sl->name, sl->desc ? sl->desc : "");
|
||||
add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0,
|
||||
ATR_NONE, buf,
|
||||
(any.a_int == defindx) ? MENU_ITEMFLAGS_SELECTED
|
||||
: MENU_ITEMFLAGS_NONE);
|
||||
}
|
||||
}
|
||||
Sprintf(buf, "Select %ssymbol set:",
|
||||
rogueflag ? "rogue level " : "");
|
||||
end_menu(tmpwin, buf);
|
||||
n = select_menu(tmpwin, PICK_ONE, &symset_pick);
|
||||
if (n > 0) {
|
||||
chosen = symset_pick[0].item.a_int;
|
||||
/* if picking non-preselected entry yields 2, make sure
|
||||
that we're going with the non-preselected one */
|
||||
if (n == 2 && chosen == defindx)
|
||||
chosen = symset_pick[1].item.a_int;
|
||||
chosen -= 2; /* convert menu index to symset index;
|
||||
* "Default symbols" have index -1 */
|
||||
free((genericptr_t) symset_pick);
|
||||
} else if (n == 0 && defindx > 0) {
|
||||
chosen = defindx - 2;
|
||||
}
|
||||
destroy_nhwindow(tmpwin);
|
||||
|
||||
if (chosen > -1) {
|
||||
/* chose an actual symset name from file */
|
||||
for (sl = g.symset_list; sl; sl = sl->next)
|
||||
if (sl->idx == chosen)
|
||||
break;
|
||||
if (sl) {
|
||||
/* free the now stale attributes */
|
||||
clear_symsetentry(which_set, TRUE);
|
||||
|
||||
/* transfer only the name of the symbol set */
|
||||
g.symset[which_set].name = dupstr(sl->name);
|
||||
ready_to_switch = TRUE;
|
||||
}
|
||||
} else if (chosen == -1) {
|
||||
/* explicit selection of defaults */
|
||||
/* free the now stale symset attributes */
|
||||
clear_symsetentry(which_set, TRUE);
|
||||
} else
|
||||
nothing_to_do = TRUE;
|
||||
} else if (!res) {
|
||||
/* The symbols file could not be accessed */
|
||||
pline("Unable to access \"%s\" file.", SYMBOLS);
|
||||
return TRUE;
|
||||
} else if (!g.symset_list) {
|
||||
/* The symbols file was empty */
|
||||
pline("There were no symbol sets found in \"%s\".", SYMBOLS);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
while ((sl = g.symset_list) != 0) {
|
||||
g.symset_list = sl->next;
|
||||
if (sl->name)
|
||||
free((genericptr_t) sl->name), sl->name = (char *) 0;
|
||||
if (sl->desc)
|
||||
free((genericptr_t) sl->desc), sl->desc = (char *) 0;
|
||||
free((genericptr_t) sl);
|
||||
}
|
||||
|
||||
if (nothing_to_do)
|
||||
return TRUE;
|
||||
|
||||
/* Set default symbols and clear the handling value */
|
||||
if (rogueflag)
|
||||
init_rogue_symbols();
|
||||
else
|
||||
init_primary_symbols();
|
||||
|
||||
if (g.symset[which_set].name) {
|
||||
/* non-default symbols */
|
||||
if (read_sym_file(which_set)) {
|
||||
ready_to_switch = TRUE;
|
||||
} else {
|
||||
clear_symsetentry(which_set, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ready_to_switch)
|
||||
switch_symbols(TRUE);
|
||||
|
||||
if (Is_rogue_level(&u.uz)) {
|
||||
if (rogueflag)
|
||||
assign_graphics(ROGUESET);
|
||||
} else if (!rogueflag)
|
||||
assign_graphics(PRIMARY);
|
||||
preference_update("symset");
|
||||
reslt = do_symset(optidx == opt_roguesymset); /* symbols.c */
|
||||
g.opt_need_redraw = TRUE;
|
||||
return optidx;
|
||||
return reslt;
|
||||
}
|
||||
|
||||
RESTORE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
static int
|
||||
handler_autopickup_exception(void)
|
||||
{
|
||||
@@ -5985,6 +5882,12 @@ initoptions_init(void)
|
||||
memcpy(allopt, allopt_init, sizeof(allopt));
|
||||
determine_ambiguities();
|
||||
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
/* make any symbol parsing quicker */
|
||||
if (!glyphid_cache_status())
|
||||
fill_glyphid_cache();
|
||||
#endif
|
||||
|
||||
/* set up the command parsing */
|
||||
reset_commands(TRUE); /* init */
|
||||
|
||||
@@ -6048,8 +5951,8 @@ initoptions_init(void)
|
||||
*/
|
||||
/* this detects the IBM-compatible console on most 386 boxes */
|
||||
if ((opts = nh_getenv("TERM")) && !strncmp(opts, "AT", 2)) {
|
||||
if (!g.symset[PRIMARY].explicitly)
|
||||
load_symset("IBMGraphics", PRIMARY);
|
||||
if (!g.symset[PRIMARYSET].explicitly)
|
||||
load_symset("IBMGraphics", PRIMARYSET);
|
||||
if (!g.symset[ROGUESET].explicitly)
|
||||
load_symset("RogueIBM", ROGUESET);
|
||||
switch_symbols(TRUE);
|
||||
@@ -6065,8 +5968,8 @@ initoptions_init(void)
|
||||
/* [could also check "xterm" which emulates vtXXX by default] */
|
||||
&& !strncmpi(opts, "vt", 2)
|
||||
&& AS && AE && index(AS, '\016') && index(AE, '\017')) {
|
||||
if (!g.symset[PRIMARY].explicitly)
|
||||
load_symset("DECGraphics", PRIMARY);
|
||||
if (!g.symset[PRIMARYSET].explicitly)
|
||||
load_symset("DECGraphics", PRIMARYSET);
|
||||
switch_symbols(TRUE);
|
||||
}
|
||||
#endif
|
||||
@@ -6074,14 +5977,14 @@ initoptions_init(void)
|
||||
|
||||
#if defined(MSDOS) || defined(WIN32)
|
||||
/* Use IBM defaults. Can be overridden via config file */
|
||||
if (!g.symset[PRIMARY].explicitly)
|
||||
load_symset("IBMGraphics_2", PRIMARY);
|
||||
if (!g.symset[PRIMARYSET].explicitly)
|
||||
load_symset("IBMGraphics_2", PRIMARYSET);
|
||||
if (!g.symset[ROGUESET].explicitly)
|
||||
load_symset("RogueEpyx", ROGUESET);
|
||||
#endif
|
||||
#ifdef MAC_GRAPHICS_ENV
|
||||
if (!g.symset[PRIMARY].explicitly)
|
||||
load_symset("MACGraphics", PRIMARY);
|
||||
if (!g.symset[PRIMARYSET].explicitly)
|
||||
load_symset("MACGraphics", PRIMARYSET);
|
||||
switch_symbols(TRUE);
|
||||
#endif /* MAC_GRAPHICS_ENV */
|
||||
flags.menu_style = MENU_FULL;
|
||||
@@ -6206,7 +6109,7 @@ initoptions_finish(void)
|
||||
obj_descr[SLIME_MOLD].oc_name = "fruit";
|
||||
|
||||
sym = get_othersym(SYM_BOULDER,
|
||||
Is_rogue_level(&u.uz) ? ROGUESET : PRIMARY);
|
||||
Is_rogue_level(&u.uz) ? ROGUESET : PRIMARYSET);
|
||||
if (sym)
|
||||
g.showsyms[SYM_BOULDER + SYM_OFF_X] = sym;
|
||||
reglyph_darkroom();
|
||||
@@ -6229,6 +6132,11 @@ initoptions_finish(void)
|
||||
}
|
||||
#endif
|
||||
update_rest_on_space();
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if (glyphid_cache_status())
|
||||
free_glyphid_cache();
|
||||
apply_customizations_to_symset(g.currentgraphics);
|
||||
#endif
|
||||
g.opt_initial = FALSE;
|
||||
return;
|
||||
}
|
||||
@@ -8195,128 +8103,6 @@ free_autopickup_exceptions(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* bundle some common usage into one easy-to-use routine */
|
||||
int
|
||||
load_symset(const char *s, int which_set)
|
||||
{
|
||||
clear_symsetentry(which_set, TRUE);
|
||||
|
||||
if (g.symset[which_set].name)
|
||||
free((genericptr_t) g.symset[which_set].name);
|
||||
g.symset[which_set].name = dupstr(s);
|
||||
|
||||
if (read_sym_file(which_set)) {
|
||||
switch_symbols(TRUE);
|
||||
} else {
|
||||
clear_symsetentry(which_set, TRUE);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
free_symsets(void)
|
||||
{
|
||||
clear_symsetentry(PRIMARY, TRUE);
|
||||
clear_symsetentry(ROGUESET, TRUE);
|
||||
|
||||
/* symset_list is cleaned up as soon as it's used, so we shouldn't
|
||||
have to anything about it here */
|
||||
/* assert( symset_list == NULL ); */
|
||||
}
|
||||
|
||||
/* Parse the value of a SYMBOLS line from a config file */
|
||||
boolean
|
||||
parsesymbols(register char *opts, int which_set)
|
||||
{
|
||||
int val;
|
||||
char *op, *symname, *strval;
|
||||
struct symparse *symp;
|
||||
|
||||
if ((op = index(opts, ',')) != 0) {
|
||||
*op++ = 0;
|
||||
if (!parsesymbols(op, which_set))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* S_sample:string */
|
||||
symname = opts;
|
||||
strval = index(opts, ':');
|
||||
if (!strval)
|
||||
strval = index(opts, '=');
|
||||
if (!strval)
|
||||
return FALSE;
|
||||
*strval++ = '\0';
|
||||
|
||||
/* strip leading and trailing white space from symname and strval */
|
||||
mungspaces(symname);
|
||||
mungspaces(strval);
|
||||
|
||||
symp = match_sym(symname);
|
||||
if (!symp)
|
||||
return FALSE;
|
||||
|
||||
if (symp->range && symp->range != SYM_CONTROL) {
|
||||
val = sym_val(strval);
|
||||
if (which_set == ROGUESET)
|
||||
update_ov_rogue_symset(symp, val);
|
||||
else
|
||||
update_ov_primary_symset(symp, val);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct symparse *
|
||||
match_sym(char *buf)
|
||||
{
|
||||
int i;
|
||||
struct alternate_parse {
|
||||
const char *altnm;
|
||||
const char *nm;
|
||||
} alternates[] = {
|
||||
{ "S_armour" , "S_armor" },
|
||||
{ "S_explode1" , "S_expl_tl" },
|
||||
{ "S_explode2" , "S_expl_tc" },
|
||||
{ "S_explode3" , "S_expl_tr" },
|
||||
{ "S_explode4" , "S_expl_ml" },
|
||||
{ "S_explode5" , "S_expl_mc" },
|
||||
{ "S_explode6" , "S_expl_mr" },
|
||||
{ "S_explode7" , "S_expl_bl" },
|
||||
{ "S_explode8" , "S_expl_bc" },
|
||||
{ "S_explode9" , "S_expl_br" },
|
||||
};
|
||||
unsigned len = Strlen(buf);
|
||||
const char *p = index(buf, ':'), *q = index(buf, '=');
|
||||
struct symparse *sp = loadsyms;
|
||||
|
||||
if (!p || (q && q < p))
|
||||
p = q;
|
||||
if (p) {
|
||||
/* note: there will be at most one space before the '='
|
||||
because caller has condensed buf[] with mungspaces() */
|
||||
if (p > buf && p[-1] == ' ')
|
||||
p--;
|
||||
len = (int) (p - buf);
|
||||
}
|
||||
while (sp->range) {
|
||||
if ((len >= Strlen(sp->name)) && !strncmpi(buf, sp->name, len))
|
||||
return sp;
|
||||
sp++;
|
||||
}
|
||||
for (i = 0; i < SIZE(alternates); ++i) {
|
||||
if ((len >= strlen(alternates[i].altnm))
|
||||
&& !strncmpi(buf, alternates[i].altnm, len)) {
|
||||
sp = loadsyms;
|
||||
while (sp->range) {
|
||||
if (!strcmp(alternates[i].nm, sp->name))
|
||||
return sp;
|
||||
sp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (struct symparse *) 0;
|
||||
}
|
||||
|
||||
int
|
||||
sym_val(const char *strval) /* up to 4*BUFSZ-1 long; only first few
|
||||
chars matter */
|
||||
|
||||
730
src/symbols.c
730
src/symbols.c
@@ -15,13 +15,18 @@ void (*decgraphics_mode_callback)(void) = 0; /* set in tty_start_screen() */
|
||||
void (*ibmgraphics_mode_callback)(void) = 0; /* set in tty_start_screen() */
|
||||
void (*ascgraphics_mode_callback)(void) = 0; /* set in tty_start_screen() */
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
void (*ibmgraphics_mode_callback)(void) = 0; /* set in tty_start_screen() */
|
||||
#endif
|
||||
#ifdef CURSES_GRAPHICS
|
||||
void (*cursesgraphics_mode_callback)(void) = 0;
|
||||
#endif
|
||||
/*
|
||||
#if defined(TTY_GRAPHICS) && defined(WIN32)
|
||||
void (*ibmgraphics_mode_callback)(void) = 0;
|
||||
#endif
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
void (*utf8graphics_mode_callback)(void) = 0; /* set in tty_start_screen and
|
||||
found in unixtty, windtty, etc */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Explanations of the functions found below:
|
||||
*
|
||||
* init_symbols()
|
||||
@@ -56,7 +61,7 @@ void (*cursesgraphics_mode_callback)(void) = 0;
|
||||
* If arg is ROGUESET, this places the rogue level
|
||||
* symbols from g.rogue_syms into g.showsyms.
|
||||
*
|
||||
* If arg is PRIMARY, this places the symbols
|
||||
* If arg is PRIMARYSET, this places the symbols
|
||||
* from g.primary_syms into g.showsyms.
|
||||
*
|
||||
* update_primary_symset()
|
||||
@@ -97,7 +102,7 @@ init_showsyms(void)
|
||||
for (i = 0; i < WARNCOUNT; i++)
|
||||
g.showsyms[i + SYM_OFF_W] = def_warnsyms[i].sym;
|
||||
for (i = 0; i < MAXOTHER; i++)
|
||||
g.showsyms[i + SYM_OFF_X] = get_othersym(i, PRIMARY);
|
||||
g.showsyms[i + SYM_OFF_X] = get_othersym(i, PRIMARYSET);
|
||||
}
|
||||
|
||||
/* initialize defaults for the overrides to the rogue symset */
|
||||
@@ -169,9 +174,9 @@ init_primary_symbols(void)
|
||||
for (i = 0; i < WARNCOUNT; i++)
|
||||
g.primary_syms[i + SYM_OFF_W] = def_warnsyms[i].sym;
|
||||
for (i = 0; i < MAXOTHER; i++)
|
||||
g.primary_syms[i + SYM_OFF_X] = get_othersym(i, PRIMARY);
|
||||
g.primary_syms[i + SYM_OFF_X] = get_othersym(i, PRIMARYSET);
|
||||
|
||||
clear_symsetentry(PRIMARY, FALSE);
|
||||
clear_symsetentry(PRIMARYSET, FALSE);
|
||||
}
|
||||
|
||||
/* initialize defaults for the rogue symset */
|
||||
@@ -224,7 +229,7 @@ assign_graphics(int whichset)
|
||||
g.currentgraphics = ROGUESET;
|
||||
break;
|
||||
|
||||
case PRIMARY:
|
||||
case PRIMARYSET:
|
||||
default:
|
||||
for (i = 0; i < SYM_MAX; i++)
|
||||
g.showsyms[i] = g.ov_primary_syms[i] ? g.ov_primary_syms[i]
|
||||
@@ -234,7 +239,7 @@ assign_graphics(int whichset)
|
||||
if (iflags.grmode)
|
||||
tileview(TRUE);
|
||||
#endif
|
||||
g.currentgraphics = PRIMARY;
|
||||
g.currentgraphics = PRIMARYSET;
|
||||
break;
|
||||
}
|
||||
reset_glyphmap(gm_symchange);
|
||||
@@ -267,6 +272,14 @@ switch_symbols(int nondefault)
|
||||
if (SYMHANDLING(H_CURS) && cursesgraphics_mode_callback)
|
||||
(*cursesgraphics_mode_callback)();
|
||||
# endif
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
if (SYMHANDLING(H_IBM) && ibmgraphics_mode_callback)
|
||||
(*ibmgraphics_mode_callback)();
|
||||
#endif
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if (SYMHANDLING(H_UTF8) && utf8graphics_mode_callback)
|
||||
(*utf8graphics_mode_callback)();
|
||||
#endif
|
||||
} else {
|
||||
init_primary_symbols();
|
||||
@@ -275,25 +288,25 @@ switch_symbols(int nondefault)
|
||||
}
|
||||
|
||||
void
|
||||
update_ov_primary_symset(struct symparse* symp, int val)
|
||||
update_ov_primary_symset(const struct symparse* symp, int val)
|
||||
{
|
||||
g.ov_primary_syms[symp->idx] = val;
|
||||
}
|
||||
|
||||
void
|
||||
update_ov_rogue_symset(struct symparse* symp, int val)
|
||||
update_ov_rogue_symset(const struct symparse* symp, int val)
|
||||
{
|
||||
g.ov_rogue_syms[symp->idx] = val;
|
||||
}
|
||||
|
||||
void
|
||||
update_primary_symset(struct symparse* symp, int val)
|
||||
update_primary_symset(const struct symparse* symp, int val)
|
||||
{
|
||||
g.primary_syms[symp->idx] = val;
|
||||
}
|
||||
|
||||
void
|
||||
update_rogue_symset(struct symparse* symp, int val)
|
||||
update_rogue_symset(const struct symparse* symp, int val)
|
||||
{
|
||||
g.rogue_syms[symp->idx] = val;
|
||||
}
|
||||
@@ -318,7 +331,20 @@ clear_symsetentry(int which_set, boolean name_too)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
boolean symset_is_compatible(enum symset_handling_types handling, unsigned long wincap2)
|
||||
{
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if ((handling == H_UTF8) &&
|
||||
(((wincap2 & WC2_U_UTF8STR) == 0)
|
||||
|| ((wincap2 & WC2_U_24BITCOLOR) == 0)))
|
||||
return FALSE;
|
||||
#else
|
||||
nhUse(handling);
|
||||
nhUse(wincap2);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
* If you are adding code somewhere to be able to recognize
|
||||
* particular types of symset "handling", define a
|
||||
* H_XXX macro in include/sym.h and add the name
|
||||
@@ -330,6 +356,7 @@ const char *known_handling[] = {
|
||||
"DEC", /* H_DEC */
|
||||
"CURS", /* H_CURS */
|
||||
"MAC", /* H_MAC -- pre-OSX MACgraphics */
|
||||
"UTF8", /* H_UTF8 */
|
||||
(const char *) 0,
|
||||
};
|
||||
|
||||
@@ -377,4 +404,677 @@ const struct symparse loadsyms[] = {
|
||||
{ 0, 0, (const char *) 0 } /* fence post */
|
||||
};
|
||||
|
||||
boolean
|
||||
proc_symset_line(char *buf)
|
||||
{
|
||||
return !((boolean) parse_sym_line(buf, g.symset_which_set));
|
||||
}
|
||||
|
||||
/* returns 0 on error */
|
||||
int
|
||||
parse_sym_line(char *buf, int which_set)
|
||||
{
|
||||
int val, i;
|
||||
const struct symparse *symp = (struct symparse *) 0;
|
||||
char *bufp, *commentp, *altp;
|
||||
int glyph = NO_GLYPH;
|
||||
boolean enhanced_unavailable = FALSE, is_glyph = FALSE;
|
||||
|
||||
if (strlen(buf) >= BUFSZ)
|
||||
buf[BUFSZ - 1] = '\0';
|
||||
/* convert each instance of whitespace (tabs, consecutive spaces)
|
||||
into a single space; leading and trailing spaces are stripped */
|
||||
mungspaces(buf);
|
||||
|
||||
/* remove trailing comment, if any (this isn't strictly needed for
|
||||
individual symbols, and it won't matter if "X#comment" without
|
||||
separating space slips through; for handling or set description,
|
||||
symbol set creator is responsible for preceding '#' with a space
|
||||
and that comment itself doesn't contain " #") */
|
||||
if ((commentp = rindex(buf, '#')) != 0 && commentp[-1] == ' ')
|
||||
commentp[-1] = '\0';
|
||||
|
||||
/* find the '=' or ':' */
|
||||
bufp = index(buf, '=');
|
||||
altp = index(buf, ':');
|
||||
if (!bufp || (altp && altp < bufp))
|
||||
bufp = altp;
|
||||
if (!bufp) {
|
||||
if (strncmpi(buf, "finish", 6) == 0) {
|
||||
/* end current graphics set */
|
||||
if (g.chosen_symset_start)
|
||||
g.chosen_symset_end = TRUE;
|
||||
g.chosen_symset_start = FALSE;
|
||||
return 1;
|
||||
}
|
||||
config_error_add("No \"finish\"");
|
||||
return 0;
|
||||
}
|
||||
/* skip '=' and space which follows, if any */
|
||||
++bufp;
|
||||
if (*bufp == ' ')
|
||||
++bufp;
|
||||
|
||||
|
||||
symp = match_sym(buf);
|
||||
if (!symp && buf[0] == 'G' && buf[1] == '_') {
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
is_glyph = match_glyph(buf);
|
||||
#else
|
||||
enhanced_unavailable = TRUE;
|
||||
#endif
|
||||
}
|
||||
if (!symp && !is_glyph && !enhanced_unavailable) {
|
||||
config_error_add("Unknown sym keyword");
|
||||
return 0;
|
||||
}
|
||||
if (symp) {
|
||||
if (!g.symset[which_set].name) {
|
||||
/* A null symset name indicates that we're just
|
||||
building a pick-list of possible symset
|
||||
values from the file, so only do that */
|
||||
if (symp->range == SYM_CONTROL) {
|
||||
struct symsetentry *tmpsp, *lastsp;
|
||||
|
||||
for (lastsp = g.symset_list; lastsp; lastsp = lastsp->next)
|
||||
if (!lastsp->next)
|
||||
break;
|
||||
switch (symp->idx) {
|
||||
case 0:
|
||||
tmpsp = (struct symsetentry *) alloc(sizeof *tmpsp);
|
||||
tmpsp->next = (struct symsetentry *) 0;
|
||||
if (!lastsp)
|
||||
g.symset_list = tmpsp;
|
||||
else
|
||||
lastsp->next = tmpsp;
|
||||
tmpsp->idx = g.symset_count++;
|
||||
tmpsp->name = dupstr(bufp);
|
||||
tmpsp->desc = (char *) 0;
|
||||
tmpsp->handling = H_UNK;
|
||||
/* initialize restriction bits */
|
||||
tmpsp->nocolor = 0;
|
||||
tmpsp->primary = 0;
|
||||
tmpsp->rogue = 0;
|
||||
break;
|
||||
case 2:
|
||||
/* handler type identified */
|
||||
tmpsp = lastsp; /* most recent symset */
|
||||
for (i = 0; known_handling[i]; ++i)
|
||||
if (!strcmpi(known_handling[i], bufp)) {
|
||||
tmpsp->handling = i;
|
||||
break; /* for loop */
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
/* description:something */
|
||||
tmpsp = lastsp; /* most recent symset */
|
||||
if (tmpsp && !tmpsp->desc)
|
||||
tmpsp->desc = dupstr(bufp);
|
||||
break;
|
||||
case 5:
|
||||
/* restrictions: xxxx*/
|
||||
tmpsp = lastsp; /* most recent symset */
|
||||
for (i = 0; known_restrictions[i]; ++i) {
|
||||
if (!strcmpi(known_restrictions[i], bufp)) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
tmpsp->primary = 1;
|
||||
break;
|
||||
case 1:
|
||||
tmpsp->rogue = 1;
|
||||
break;
|
||||
}
|
||||
break; /* while loop */
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (symp->range && symp->range == SYM_CONTROL) {
|
||||
switch (symp->idx) {
|
||||
case 0:
|
||||
/* start of symset */
|
||||
if (!strcmpi(bufp, g.symset[which_set].name)) {
|
||||
/* matches desired one */
|
||||
g.chosen_symset_start = TRUE;
|
||||
/* these init_*() functions clear symset fields too */
|
||||
if (which_set == ROGUESET)
|
||||
init_rogue_symbols();
|
||||
else if (which_set == PRIMARYSET)
|
||||
init_primary_symbols();
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* finish symset */
|
||||
if (g.chosen_symset_start)
|
||||
g.chosen_symset_end = TRUE;
|
||||
g.chosen_symset_start = FALSE;
|
||||
break;
|
||||
case 2:
|
||||
/* handler type identified */
|
||||
if (g.chosen_symset_start)
|
||||
set_symhandling(bufp, which_set);
|
||||
break;
|
||||
/* case 3: (description) is ignored here */
|
||||
case 4: /* color:off */
|
||||
if (g.chosen_symset_start) {
|
||||
if (bufp) {
|
||||
if (!strcmpi(bufp, "true") || !strcmpi(bufp, "yes")
|
||||
|| !strcmpi(bufp, "on"))
|
||||
g.symset[which_set].nocolor = 0;
|
||||
else if (!strcmpi(bufp, "false")
|
||||
|| !strcmpi(bufp, "no")
|
||||
|| !strcmpi(bufp, "off"))
|
||||
g.symset[which_set].nocolor = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5: /* restrictions: xxxx*/
|
||||
if (g.chosen_symset_start) {
|
||||
int n = 0;
|
||||
|
||||
while (known_restrictions[n]) {
|
||||
if (!strcmpi(known_restrictions[n], bufp)) {
|
||||
switch (n) {
|
||||
case 0:
|
||||
g.symset[which_set].primary = 1;
|
||||
break;
|
||||
case 1:
|
||||
g.symset[which_set].rogue = 1;
|
||||
break;
|
||||
}
|
||||
break; /* while loop */
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Not SYM_CONTROL */
|
||||
if (g.symset[which_set].handling != H_UTF8) {
|
||||
val = sym_val(bufp);
|
||||
if (g.chosen_symset_start) {
|
||||
if (which_set == PRIMARYSET) {
|
||||
update_primary_symset(symp, val);
|
||||
} else if (which_set == ROGUESET) {
|
||||
update_rogue_symset(symp, val);
|
||||
}
|
||||
}
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
} else {
|
||||
glyphrep_to_custom_map_entries(buf, &glyph);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef ENHANCED_SYMBOLS
|
||||
nhUse(glyph);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
set_symhandling(char *handling, int which_set)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
g.symset[which_set].handling = H_UNK;
|
||||
while (known_handling[i]) {
|
||||
if (!strcmpi(known_handling[i], handling)) {
|
||||
g.symset[which_set].handling = i;
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* bundle some common usage into one easy-to-use routine */
|
||||
int
|
||||
load_symset(const char *s, int which_set)
|
||||
{
|
||||
clear_symsetentry(which_set, TRUE);
|
||||
|
||||
if (g.symset[which_set].name)
|
||||
free((genericptr_t) g.symset[which_set].name);
|
||||
g.symset[which_set].name = dupstr(s);
|
||||
|
||||
if (read_sym_file(which_set)) {
|
||||
switch_symbols(TRUE);
|
||||
} else {
|
||||
clear_symsetentry(which_set, TRUE);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
free_symsets(void)
|
||||
{
|
||||
clear_symsetentry(PRIMARYSET, TRUE);
|
||||
clear_symsetentry(ROGUESET, TRUE);
|
||||
|
||||
/* symset_list is cleaned up as soon as it's used, so we shouldn't
|
||||
have to anything about it here */
|
||||
/* assert( symset_list == NULL ); */
|
||||
}
|
||||
|
||||
/* Parse the value of a SYMBOLS line from a config file */
|
||||
boolean
|
||||
parsesymbols(register char *opts, int which_set)
|
||||
{
|
||||
int val;
|
||||
char *op, *symname, *strval;
|
||||
const struct symparse *symp;
|
||||
boolean is_glyph = FALSE;
|
||||
|
||||
if ((op = index(opts, ',')) != 0) {
|
||||
*op++ = 0;
|
||||
if (!parsesymbols(op, which_set))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* S_sample:string */
|
||||
symname = opts;
|
||||
strval = index(opts, ':');
|
||||
if (!strval)
|
||||
strval = index(opts, '=');
|
||||
if (!strval)
|
||||
return FALSE;
|
||||
*strval++ = '\0';
|
||||
|
||||
/* strip leading and trailing white space from symname and strval */
|
||||
mungspaces(symname);
|
||||
mungspaces(strval);
|
||||
|
||||
symp = match_sym(symname);
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if (!symp && symname[0] == 'G' && symname[1] == '_') {
|
||||
is_glyph = match_glyph(symname);
|
||||
}
|
||||
#endif
|
||||
if (!symp && !is_glyph)
|
||||
return FALSE;
|
||||
if (symp) {
|
||||
if (symp->range && symp->range != SYM_CONTROL) {
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
int glyph;
|
||||
#endif
|
||||
|
||||
if ((g.symset[which_set].handling == H_UTF8)
|
||||
|| (strval && (lowc(strval[0]) == 'u') && (strval[1] == '+'))) {
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
char buf[BUFSZ];
|
||||
|
||||
Snprintf(buf, sizeof buf, "%s:%s", opts, strval);
|
||||
glyphrep_to_custom_map_entries(buf, &glyph);
|
||||
#endif /* ENHANCED_SYMBOLS */
|
||||
} else {
|
||||
val = sym_val(strval);
|
||||
if (which_set == ROGUESET)
|
||||
update_ov_rogue_symset(symp, val);
|
||||
else
|
||||
update_ov_primary_symset(symp, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const struct symparse *
|
||||
match_sym(char *buf)
|
||||
{
|
||||
int i;
|
||||
struct alternate_parse {
|
||||
const char *altnm;
|
||||
const char *nm;
|
||||
} alternates[] = {
|
||||
{ "S_armour", "S_armor" }, { "S_explode1", "S_expl_tl" },
|
||||
{ "S_explode2", "S_expl_tc" }, { "S_explode3", "S_expl_tr" },
|
||||
{ "S_explode4", "S_expl_ml" }, { "S_explode5", "S_expl_mc" },
|
||||
{ "S_explode6", "S_expl_mr" }, { "S_explode7", "S_expl_bl" },
|
||||
{ "S_explode8", "S_expl_bc" }, { "S_explode9", "S_expl_br" },
|
||||
};
|
||||
size_t len = strlen(buf);
|
||||
const char *p = index(buf, ':'), *q = index(buf, '=');
|
||||
const struct symparse *sp = loadsyms;
|
||||
|
||||
if (!p || (q && q < p))
|
||||
p = q;
|
||||
if (p) {
|
||||
/* note: there will be at most one space before the '='
|
||||
because caller has condensed buf[] with mungspaces() */
|
||||
if (p > buf && p[-1] == ' ')
|
||||
p--;
|
||||
len = (int) (p - buf);
|
||||
}
|
||||
while (sp->range) {
|
||||
if ((len >= strlen(sp->name)) && !strncmpi(buf, sp->name, len))
|
||||
return sp;
|
||||
sp++;
|
||||
}
|
||||
for (i = 0; i < SIZE(alternates); ++i) {
|
||||
if ((len >= strlen(alternates[i].altnm))
|
||||
&& !strncmpi(buf, alternates[i].altnm, len)) {
|
||||
sp = loadsyms;
|
||||
while (sp->range) {
|
||||
if (!strcmp(alternates[i].nm, sp->name))
|
||||
return sp;
|
||||
sp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (struct symparse *) 0;
|
||||
}
|
||||
|
||||
DISABLE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
/*
|
||||
* this is called from options.c to do the symset work.
|
||||
*/
|
||||
int
|
||||
do_symset(boolean rogueflag)
|
||||
{
|
||||
winid tmpwin;
|
||||
anything any;
|
||||
int n;
|
||||
char buf[BUFSZ];
|
||||
menu_item *symset_pick = (menu_item *) 0;
|
||||
boolean ready_to_switch = FALSE,
|
||||
nothing_to_do = FALSE;
|
||||
char *symset_name, fmtstr[20];
|
||||
struct symsetentry *sl;
|
||||
int res, which_set, setcount = 0, chosen = -2, defindx = 0;
|
||||
|
||||
which_set = rogueflag ? ROGUESET : PRIMARYSET;
|
||||
g.symset_list = (struct symsetentry *) 0;
|
||||
/* clear symset[].name as a flag to read_sym_file() to build list */
|
||||
symset_name = g.symset[which_set].name;
|
||||
g.symset[which_set].name = (char *) 0;
|
||||
|
||||
res = read_sym_file(which_set);
|
||||
/* put symset name back */
|
||||
g.symset[which_set].name = symset_name;
|
||||
|
||||
if (res && g.symset_list) {
|
||||
int thissize,
|
||||
biggest = (int) (sizeof "Default Symbols" - sizeof ""),
|
||||
big_desc = 0;
|
||||
|
||||
for (sl = g.symset_list; sl; sl = sl->next) {
|
||||
/* check restrictions */
|
||||
if (rogueflag ? sl->primary : sl->rogue)
|
||||
continue;
|
||||
#ifndef MAC_GRAPHICS_ENV
|
||||
if (sl->handling == H_MAC)
|
||||
continue;
|
||||
#endif
|
||||
#ifndef ENHANCED_SYMBOLS
|
||||
if (sl->handling == H_UTF8)
|
||||
continue;
|
||||
#endif
|
||||
setcount++;
|
||||
/* find biggest name */
|
||||
thissize = sl->name ? (int) strlen(sl->name) : 0;
|
||||
if (thissize > biggest)
|
||||
biggest = thissize;
|
||||
thissize = sl->desc ? (int) strlen(sl->desc) : 0;
|
||||
if (thissize > big_desc)
|
||||
big_desc = thissize;
|
||||
}
|
||||
if (!setcount) {
|
||||
pline("There are no appropriate %s symbol sets available.",
|
||||
rogueflag ? "rogue level" : "primary");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Sprintf(fmtstr, "%%-%ds %%s", biggest + 2);
|
||||
tmpwin = create_nhwindow(NHW_MENU);
|
||||
start_menu(tmpwin, MENU_BEHAVE_STANDARD);
|
||||
any = cg.zeroany;
|
||||
any.a_int = 1; /* -1 + 2 [see 'if (sl->name) {' below]*/
|
||||
if (!symset_name)
|
||||
defindx = any.a_int;
|
||||
add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0, ATR_NONE,
|
||||
"Default Symbols",
|
||||
(any.a_int == defindx) ? MENU_ITEMFLAGS_SELECTED
|
||||
: MENU_ITEMFLAGS_NONE);
|
||||
|
||||
for (sl = g.symset_list; sl; sl = sl->next) {
|
||||
/* check restrictions */
|
||||
if (rogueflag ? sl->primary : sl->rogue)
|
||||
continue;
|
||||
#ifndef MAC_GRAPHICS_ENV
|
||||
if (sl->handling == H_MAC)
|
||||
continue;
|
||||
#endif
|
||||
#ifndef ENHANCED_SYMBOLS
|
||||
if (sl->handling == H_UTF8)
|
||||
continue;
|
||||
#endif
|
||||
if (sl->name) {
|
||||
/* +2: sl->idx runs from 0 to N-1 for N symsets;
|
||||
+1 because Defaults are implicitly in slot [0];
|
||||
+1 again so that valid data is never 0 */
|
||||
any.a_int = sl->idx + 2;
|
||||
if (symset_name && !strcmpi(sl->name, symset_name))
|
||||
defindx = any.a_int;
|
||||
Sprintf(buf, fmtstr, sl->name, sl->desc ? sl->desc : "");
|
||||
add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0,
|
||||
ATR_NONE, buf,
|
||||
(any.a_int == defindx) ? MENU_ITEMFLAGS_SELECTED
|
||||
: MENU_ITEMFLAGS_NONE);
|
||||
}
|
||||
}
|
||||
Sprintf(buf, "Select %ssymbol set:",
|
||||
rogueflag ? "rogue level " : "");
|
||||
end_menu(tmpwin, buf);
|
||||
n = select_menu(tmpwin, PICK_ONE, &symset_pick);
|
||||
if (n > 0) {
|
||||
chosen = symset_pick[0].item.a_int;
|
||||
/* if picking non-preselected entry yields 2, make sure
|
||||
that we're going with the non-preselected one */
|
||||
if (n == 2 && chosen == defindx)
|
||||
chosen = symset_pick[1].item.a_int;
|
||||
chosen -= 2; /* convert menu index to symset index;
|
||||
* "Default symbols" have index -1 */
|
||||
free((genericptr_t) symset_pick);
|
||||
} else if (n == 0 && defindx > 0) {
|
||||
chosen = defindx - 2;
|
||||
}
|
||||
destroy_nhwindow(tmpwin);
|
||||
|
||||
if (chosen > -1) {
|
||||
/* chose an actual symset name from file */
|
||||
for (sl = g.symset_list; sl; sl = sl->next)
|
||||
if (sl->idx == chosen)
|
||||
break;
|
||||
if (sl) {
|
||||
/* free the now stale attributes */
|
||||
clear_symsetentry(which_set, TRUE);
|
||||
|
||||
/* transfer only the name of the symbol set */
|
||||
g.symset[which_set].name = dupstr(sl->name);
|
||||
ready_to_switch = TRUE;
|
||||
}
|
||||
} else if (chosen == -1) {
|
||||
/* explicit selection of defaults */
|
||||
/* free the now stale symset attributes */
|
||||
clear_symsetentry(which_set, TRUE);
|
||||
} else
|
||||
nothing_to_do = TRUE;
|
||||
} else if (!res) {
|
||||
/* The symbols file could not be accessed */
|
||||
pline("Unable to access \"%s\" file.", SYMBOLS);
|
||||
return TRUE;
|
||||
} else if (!g.symset_list) {
|
||||
/* The symbols file was empty */
|
||||
pline("There were no symbol sets found in \"%s\".", SYMBOLS);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
while ((sl = g.symset_list) != 0) {
|
||||
g.symset_list = sl->next;
|
||||
if (sl->name)
|
||||
free((genericptr_t) sl->name), sl->name = (char *) 0;
|
||||
if (sl->desc)
|
||||
free((genericptr_t) sl->desc), sl->desc = (char *) 0;
|
||||
free((genericptr_t) sl);
|
||||
}
|
||||
|
||||
if (nothing_to_do)
|
||||
return TRUE;
|
||||
|
||||
/* Set default symbols and clear the handling value */
|
||||
if (rogueflag)
|
||||
init_rogue_symbols();
|
||||
else
|
||||
init_primary_symbols();
|
||||
|
||||
if (g.symset[which_set].name) {
|
||||
/* non-default symbols */
|
||||
if (read_sym_file(which_set)) {
|
||||
ready_to_switch = TRUE;
|
||||
} else {
|
||||
clear_symsetentry(which_set, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ready_to_switch)
|
||||
switch_symbols(TRUE);
|
||||
|
||||
if (Is_rogue_level(&u.uz)) {
|
||||
if (rogueflag)
|
||||
assign_graphics(ROGUESET);
|
||||
} else if (!rogueflag)
|
||||
assign_graphics(PRIMARYSET);
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
apply_customizations_to_symset(rogueflag ? ROGUESET : PRIMARYSET);
|
||||
#endif
|
||||
preference_update("symset");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
|
||||
RESTORE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
struct customization_detail *find_display_sym_customization(
|
||||
const char *customization_name, const struct symparse *symparse,
|
||||
enum graphics_sets which_set);
|
||||
struct customization_detail *find_matching_symset_customization(
|
||||
const char *customization_name, int custtype,
|
||||
enum graphics_sets which_set);
|
||||
struct customization_detail *find_display_urep_customization(
|
||||
const char *customization_name, int glyphidx, enum graphics_sets which_set);
|
||||
void purge_custom_entries(enum graphics_sets which_set);
|
||||
extern glyph_map glyphmap[MAX_GLYPH];
|
||||
static void shuffle_customizations(void);
|
||||
|
||||
void
|
||||
apply_customizations_to_symset(enum graphics_sets which_set)
|
||||
{
|
||||
glyph_map *gm;
|
||||
struct customization_detail *details;
|
||||
|
||||
if (g.symset[which_set].handling == H_UTF8
|
||||
&& g.sym_customizations[UNICODESET].count
|
||||
&& g.sym_customizations[UNICODESET].details) {
|
||||
/* These UTF-8 customizations get applied to the glyphmap array,
|
||||
not to symset entries */
|
||||
details = g.sym_customizations[UNICODESET].details;
|
||||
while (details) {
|
||||
gm = &glyphmap[details->content.urep.glyphidx];
|
||||
(void) set_map_u(gm, details->content.urep.u.utf8str,
|
||||
details->content.urep.u.ucolor);
|
||||
details = details->next;
|
||||
}
|
||||
shuffle_customizations();
|
||||
}
|
||||
}
|
||||
/* Shuffle the customizations to match shuffled object descriptions,
|
||||
* so a red potion isn't displayed with a blue customization, and so on.
|
||||
*/
|
||||
static void
|
||||
shuffle_customizations(void)
|
||||
{
|
||||
int i;
|
||||
struct unicode_representation *tmp_u[2][NUM_OBJECTS];
|
||||
|
||||
for (i = 0; i < NUM_OBJECTS; i++) {
|
||||
tmp_u[0][i] =
|
||||
glyphmap[objects[i].oc_descr_idx + GLYPH_OBJ_OFF].u;
|
||||
tmp_u[1][i] =
|
||||
glyphmap[objects[i].oc_descr_idx + GLYPH_OBJ_PILETOP_OFF].u;
|
||||
}
|
||||
for (i = 0; i < NUM_OBJECTS; i++) {
|
||||
glyphmap[i + GLYPH_OBJ_OFF].u = tmp_u[0][i];
|
||||
glyphmap[i + GLYPH_OBJ_PILETOP_OFF].u = tmp_u[1][i];
|
||||
}
|
||||
}
|
||||
|
||||
struct customization_detail *
|
||||
find_matching_symset_customization(const char *customization_name,
|
||||
int custtype,
|
||||
enum graphics_sets which_set)
|
||||
{
|
||||
struct symset_customization *gdc = &g.sym_customizations[which_set];
|
||||
if ((gdc->custtype == custtype)
|
||||
&& (strcmp(customization_name, gdc->customization_name) != 0))
|
||||
return gdc->details;
|
||||
return (struct customization_detail *) 0;
|
||||
}
|
||||
|
||||
void
|
||||
purge_custom_entries(enum graphics_sets which_set)
|
||||
{
|
||||
struct symset_customization *gdc = &g.sym_customizations[which_set];
|
||||
struct customization_detail *details = gdc->details, *next;
|
||||
if (details) {
|
||||
next = details->next;
|
||||
if (gdc->custtype == custom_ureps) {
|
||||
if (details->content.urep.u.utf8str)
|
||||
free(details->content.urep.u.utf8str);
|
||||
details->content.urep.u.utf8str = (uint8 *) 0;
|
||||
details->content.urep.u.ucolor = 0L;
|
||||
details->content.urep.u.u256coloridx = 0L;
|
||||
} else if (gdc->custtype == custom_symbols) {
|
||||
details->content.sym.symparse = (struct symparse *) 0;
|
||||
details->content.sym.val = 0;
|
||||
}
|
||||
free(details);
|
||||
details = next;
|
||||
}
|
||||
gdc->details = 0;
|
||||
if (gdc->customization_name) {
|
||||
free((genericptr_t) gdc->customization_name);
|
||||
gdc->customization_name = 0;
|
||||
}
|
||||
gdc->count = 0;
|
||||
}
|
||||
|
||||
struct customization_detail *
|
||||
find_display_sym_customization(const char *customization_name,
|
||||
const struct symparse *symparse,
|
||||
enum graphics_sets which_set)
|
||||
{
|
||||
struct symset_customization *gdc = &g.sym_customizations[which_set];
|
||||
struct customization_detail *symdetails;
|
||||
if ((gdc->custtype == custom_symbols)
|
||||
&& (strcmp(customization_name, gdc->customization_name) == 0)) {
|
||||
symdetails = gdc->details;
|
||||
while (symdetails) {
|
||||
if (symdetails->content.sym.symparse == symparse)
|
||||
return symdetails;
|
||||
symdetails = symdetails->next;
|
||||
}
|
||||
}
|
||||
return (struct customization_detail *) 0;
|
||||
}
|
||||
#endif /* ENHANCED_SYMBOLS */
|
||||
|
||||
/*symbols.c*/
|
||||
|
||||
1123
src/utf8map.c
Normal file
1123
src/utf8map.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1375,7 +1375,7 @@ glyph2symidx(int glyph)
|
||||
glyph_info glyphinfo;
|
||||
|
||||
map_glyphinfo(0, 0, glyph, 0, &glyphinfo);
|
||||
return glyphinfo.gm.symidx;
|
||||
return glyphinfo.gm.sym.symidx;
|
||||
}
|
||||
|
||||
char *
|
||||
@@ -1387,10 +1387,37 @@ encglyph(int glyph)
|
||||
return encbuf;
|
||||
}
|
||||
|
||||
int
|
||||
decode_glyph(const char *str, int *glyph_ptr)
|
||||
{
|
||||
static const char hex[] = "00112233445566778899aAbBcCdDeEfF";
|
||||
int rndchk = 0, dcount = 0, retval = 0;
|
||||
const char *dp;
|
||||
|
||||
for (; *str && ++dcount <= 4; ++str) {
|
||||
if ((dp = index(hex, *str)) != 0) {
|
||||
retval++;
|
||||
rndchk = (rndchk * 16) + ((int) (dp - hex) / 2);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if (rndchk == g.context.rndencode) {
|
||||
*glyph_ptr = dcount = 0;
|
||||
for (; *str && ++dcount <= 4; ++str) {
|
||||
if ((dp = index(hex, *str)) != 0) {
|
||||
retval++;
|
||||
*glyph_ptr = (*glyph_ptr * 16) + ((int) (dp - hex) / 2);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
decode_mixed(char *buf, const char *str)
|
||||
{
|
||||
static const char hex[] = "00112233445566778899aAbBcCdDeEfF";
|
||||
char *put = buf;
|
||||
glyph_info glyphinfo = nul_glyphinfo;
|
||||
|
||||
@@ -1399,27 +1426,16 @@ decode_mixed(char *buf, const char *str)
|
||||
|
||||
while (*str) {
|
||||
if (*str == '\\') {
|
||||
int rndchk, dcount, so, gv;
|
||||
const char *dp, *save_str;
|
||||
int dcount, so, gv;
|
||||
const char *save_str;
|
||||
|
||||
save_str = str++;
|
||||
switch (*str) {
|
||||
case 'G': /* glyph value \GXXXXNNNN*/
|
||||
rndchk = dcount = 0;
|
||||
for (++str; *str && ++dcount <= 4; ++str)
|
||||
if ((dp = index(hex, *str)) != 0)
|
||||
rndchk = (rndchk * 16) + ((int) (dp - hex) / 2);
|
||||
else
|
||||
break;
|
||||
if (rndchk == g.context.rndencode) {
|
||||
gv = dcount = 0;
|
||||
for (; *str && ++dcount <= 4; ++str)
|
||||
if ((dp = index(hex, *str)) != 0)
|
||||
gv = (gv * 16) + ((int) (dp - hex) / 2);
|
||||
else
|
||||
break;
|
||||
if ((dcount = decode_glyph(str + 1, &gv))) {
|
||||
str += (dcount + 1);
|
||||
map_glyphinfo(0, 0, gv, 0, &glyphinfo);
|
||||
so = glyphinfo.gm.symidx;
|
||||
so = glyphinfo.gm.sym.symidx;
|
||||
*put++ = g.showsyms[so];
|
||||
/* 'str' is ready for the next loop iteration and '*str'
|
||||
should not be copied at the end of this iteration */
|
||||
@@ -1429,25 +1445,6 @@ decode_mixed(char *buf, const char *str)
|
||||
str = save_str;
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
case 'S': /* symbol offset */
|
||||
so = rndchk = dcount = 0;
|
||||
for (++str; *str && ++dcount <= 4; ++str)
|
||||
if ((dp = index(hex, *str)) != 0)
|
||||
rndchk = (rndchk * 16) + ((int) (dp - hex) / 2);
|
||||
else
|
||||
break;
|
||||
if (rndchk == g.context.rndencode) {
|
||||
dcount = 0;
|
||||
for (; *str && ++dcount <= 2; ++str)
|
||||
if ((dp = index(hex, *str)) != 0)
|
||||
so = (so * 16) + ((int) (dp - hex) / 2);
|
||||
else
|
||||
break;
|
||||
}
|
||||
*put++ = g.showsyms[so];
|
||||
break;
|
||||
#endif
|
||||
case '\\':
|
||||
break;
|
||||
case '\0':
|
||||
@@ -1467,6 +1464,7 @@ decode_mixed(char *buf, const char *str)
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This differs from putstr() because the str parameter can
|
||||
* contain a sequence of characters representing:
|
||||
|
||||
@@ -361,7 +361,7 @@ process_options(int argc, char *argv[])
|
||||
|| !strcmpi(*argv, "-debug")) {
|
||||
wizard = TRUE, discover = FALSE;
|
||||
} else if (!strncmpi(*argv, "-DECgraphics", l)) {
|
||||
load_symset("DECGraphics", PRIMARY);
|
||||
load_symset("DECGraphics", PRIMARYSET);
|
||||
switch_symbols(TRUE);
|
||||
} else {
|
||||
raw_printf("Unknown option: %.60s", *argv);
|
||||
@@ -391,7 +391,7 @@ process_options(int argc, char *argv[])
|
||||
case 'I':
|
||||
case 'i':
|
||||
if (!strncmpi(*argv, "-IBMgraphics", l)) {
|
||||
load_symset("IBMGraphics", PRIMARY);
|
||||
load_symset("IBMGraphics", PRIMARYSET);
|
||||
load_symset("RogueIBM", ROGUESET);
|
||||
switch_symbols(TRUE);
|
||||
} else {
|
||||
|
||||
@@ -561,7 +561,7 @@ process_options(int argc, char *argv[])
|
||||
case 'I':
|
||||
case 'i':
|
||||
if (!strncmpi(argv[0] + 1, "IBM", 3)) {
|
||||
load_symset("IBMGraphics", PRIMARY);
|
||||
load_symset("IBMGraphics", PRIMARYSET);
|
||||
load_symset("RogueIBM", ROGUESET);
|
||||
switch_symbols(TRUE);
|
||||
}
|
||||
@@ -569,7 +569,7 @@ process_options(int argc, char *argv[])
|
||||
/* case 'D': */
|
||||
case 'd':
|
||||
if (!strncmpi(argv[0] + 1, "DEC", 3)) {
|
||||
load_symset("DECGraphics", PRIMARY);
|
||||
load_symset("DECGraphics", PRIMARYSET);
|
||||
switch_symbols(TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -393,7 +393,7 @@ init_sco_cons(void)
|
||||
if (WINDOWPORT("tty") && sco_flag_console) {
|
||||
atexit(sco_mapon);
|
||||
sco_mapoff();
|
||||
load_symset("IBMGraphics", PRIMARY);
|
||||
load_symset("IBMGraphics", PRIMARYSET);
|
||||
load_symset("RogueIBM", ROGUESET);
|
||||
switch_symbols(TRUE);
|
||||
#ifdef TEXTCOLOR
|
||||
@@ -485,3 +485,15 @@ error(const char *s, ...)
|
||||
|
||||
RESTORE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
/*
|
||||
* set in tty_start_screen() and allows
|
||||
* OS-specific changes that may be
|
||||
* required for support of utf8.
|
||||
*/
|
||||
void
|
||||
tty_utf8graphics_fixup(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -488,7 +488,7 @@ HACKCSRC = allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \
|
||||
rip.c rnd.c role.c rumors.c save.c sfstruct.c \
|
||||
shk.c shknam.c sit.c sounds.c \
|
||||
sp_lev.c spell.c steal.c steed.c symbols.c sys.c teleport.c \
|
||||
timeout.c topten.c track.c trap.c u_init.c \
|
||||
timeout.c topten.c track.c trap.c u_init.c utf8map.c \
|
||||
uhitm.c vault.c version.c vision.c weapon.c were.c wield.c \
|
||||
windows.c wizard.c worm.c worn.c write.c zap.c
|
||||
|
||||
@@ -580,8 +580,8 @@ HOBJ = $(TARGETPFX)allmain.o $(TARGETPFX)alloc.o \
|
||||
$(TARGETPFX)symbols.o $(TARGETPFX)sys.o $(TARGETPFX)steal.o \
|
||||
$(TARGETPFX)steed.o $(TARGETPFX)teleport.o $(TARGETPFX)timeout.o \
|
||||
$(TARGETPFX)topten.o $(TARGETPFX)track.o $(TARGETPFX)trap.o \
|
||||
$(TARGETPFX)u_init.o $(TARGETPFX)uhitm.o $(TARGETPFX)vault.o \
|
||||
$(TARGETPFX)vision.o $(TARGETPFX)weapon.o \
|
||||
$(TARGETPFX)u_init.o $(TARGETPFX)uhitm.o $(TARGETPFX)utf8map.o \
|
||||
$(TARGETPFX)vault.o $(TARGETPFX)vision.o $(TARGETPFX)weapon.o \
|
||||
$(TARGETPFX)were.o $(TARGETPFX)wield.o $(TARGETPFX)windows.o \
|
||||
$(TARGETPFX)wizard.o $(TARGETPFX)worm.o $(TARGETPFX)worn.o \
|
||||
$(TARGETPFX)write.o $(TARGETPFX)zap.o \
|
||||
|
||||
@@ -105,6 +105,9 @@ NHCFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\"
|
||||
#NHCFLAGS+=-DTTY_SOUND_ESCCODES
|
||||
#NHCFLAGS+=-DNO_CHRONICLE
|
||||
#NHCFLAGS+=-DLIVELOG
|
||||
ifdef WANT_WIN_CURSES
|
||||
NHCFLAGS+=-DCURSES_UNICODE
|
||||
endif
|
||||
|
||||
CFLAGS+= $(WINCFLAGS) #WINCFLAGS set from multiw-2.370
|
||||
CFLAGS+= $(NHCFLAGS)
|
||||
|
||||
@@ -105,6 +105,9 @@ NHCFLAGS+=-DNOMAIL
|
||||
#NHCFLAGS+=-DTTY_SOUND_ESCCODES
|
||||
#NHCFLAGS+=-DNO_CHRONICLE
|
||||
#NHCFLAGS+=-DLIVELOG
|
||||
ifdef WANT_WIN_CURSES
|
||||
NHCFLAGS+=-DCURSES_UNICODE
|
||||
endif
|
||||
|
||||
CFLAGS+= $(WINCFLAGS) #WINCFLAGS set from multiw-2.370
|
||||
CFLAGS+= $(NHCFLAGS)
|
||||
|
||||
@@ -115,7 +115,10 @@ main(int argc, char *argv[])
|
||||
#endif /* CHDIR */
|
||||
/* handle -dalthackdir, -s <score stuff>, --version, --showpaths */
|
||||
early_options(&argc, &argv, &dir);
|
||||
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if (argcheck(argc, argv, ARG_DUMPGLYPHIDS) == 2)
|
||||
exit(EXIT_SUCCESS);
|
||||
#endif
|
||||
#ifdef CHDIR
|
||||
/*
|
||||
* Change directories before we initialize the window system so
|
||||
@@ -405,7 +408,7 @@ process_options(int argc, char *argv[])
|
||||
if ((arg[1] == 'D' && !arg[2]) || !strcmpi(arg, "-debug")) {
|
||||
wizard = TRUE, discover = FALSE;
|
||||
} else if (!strncmpi(arg, "-DECgraphics", l)) {
|
||||
load_symset("DECGraphics", PRIMARY);
|
||||
load_symset("DECGraphics", PRIMARYSET);
|
||||
switch_symbols(TRUE);
|
||||
} else {
|
||||
config_error_add("Unknown option: %.60s", origarg);
|
||||
@@ -442,7 +445,7 @@ process_options(int argc, char *argv[])
|
||||
case 'I':
|
||||
case 'i':
|
||||
if (!strncmpi(arg, "-IBMgraphics", l)) {
|
||||
load_symset("IBMGraphics", PRIMARY);
|
||||
load_symset("IBMGraphics", PRIMARYSET);
|
||||
load_symset("RogueIBM", ROGUESET);
|
||||
switch_symbols(TRUE);
|
||||
} else {
|
||||
|
||||
@@ -281,7 +281,7 @@ process_options(int argc, char *argv[])
|
||||
case 'I':
|
||||
case 'i':
|
||||
if (!strncmpi(argv[0] + 1, "IBM", 3)) {
|
||||
load_symset("IBMGraphics", PRIMARY);
|
||||
load_symset("IBMGraphics", PRIMARYSET);
|
||||
load_symset("RogueIBM", ROGUESET);
|
||||
switch_symbols(TRUE);
|
||||
}
|
||||
@@ -289,7 +289,7 @@ process_options(int argc, char *argv[])
|
||||
/* case 'D': */
|
||||
case 'd':
|
||||
if (!strncmpi(argv[0] + 1, "DEC", 3)) {
|
||||
load_symset("DECGraphics", PRIMARY);
|
||||
load_symset("DECGraphics", PRIMARYSET);
|
||||
switch_symbols(TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -724,7 +724,7 @@ COREOBJS = $(addsuffix .o, allmain alloc apply artifact attrib ball bones botl c
|
||||
pager pickup pline polyself potion pray priest quest questpgr \
|
||||
random read rect region restore rip rnd role rumors \
|
||||
safeproc save sfstruct shk shknam sit sounds sp_lev spell steal steed stubs symbols sys \
|
||||
teleport timeout topten track trap u_init uhitm vault version vision \
|
||||
teleport timeout topten track trap u_init uhitm utf8map vault version vision \
|
||||
weapon were wield windmain windows windsys wizard worm worn write zap)
|
||||
|
||||
CFLAGSW = $(CFLAGS) $(COMMONDEF) $(DLBFLG) -DTILES -D_WINDOWS -DMSWIN_GRAPHICS -DSAFEPROCS -DNOTTYGRPHICS
|
||||
|
||||
@@ -435,8 +435,8 @@ HACKCSRC = allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \
|
||||
rip.c rnd.c role.c rumors.c save.c sfstruct.c \
|
||||
shk.c shknam.c sit.c sounds.c \
|
||||
sp_lev.c spell.c steal.c steed.c symbols.c sys.c teleport.c \
|
||||
timeout.c topten.c track.c trap.c u_init.c \
|
||||
uhitm.c vault.c version.c vision.c weapon.c were.c wield.c \
|
||||
timeout.c topten.c track.c trap.c u_init.c uhitm.c utf8map.c \
|
||||
vault.c version.c vision.c weapon.c were.c wield.c \
|
||||
windows.c wizard.c worm.c worn.c write.c zap.c
|
||||
|
||||
|
||||
@@ -496,10 +496,10 @@ VOBJ21 = $(O)sfstruct.o $(O)shk.o $(O)shknam.o $(O)sit.o
|
||||
VOBJ22 = $(O)sounds.o $(O)sp_lev.o $(O)spell.o $(O)steal.o
|
||||
VOBJ23 = $(O)steed.o $(O)symbols.o $(O)sys.o $(O)teleport.o
|
||||
VOBJ24 = $(O)timeout.o $(O)topten.o $(O)track.o $(O)trap.o
|
||||
VOBJ25 = $(O)u_init.o $(O)uhitm.o $(O)vault.o $(O)vision.o
|
||||
VOBJ26 = $(O)weapon.o $(O)were.o $(O)wield.o $(O)windows.o
|
||||
VOBJ27 = $(O)wizard.o $(O)worm.o $(O)worn.o $(O)write.o
|
||||
VOBJ28 = $(O)zap.o
|
||||
VOBJ25 = $(O)u_init.o $(O)uhitm.o $(O)utf8map.o $(O)vault.o
|
||||
VOBJ26 = $(O)vision.o $(O)weapon.o $(O)were.o $(O)wield.o
|
||||
VOBJ27 = $(O)windows.o $(O)wizard.o $(O)worm.o $(O)worn.o
|
||||
VOBJ28 = $(O)write.o $(O)zap.o
|
||||
|
||||
LUAOBJ = $(O)nhlua.o $(O)nhlsel.o $(O)nhlobj.o
|
||||
|
||||
@@ -510,7 +510,7 @@ DLBOBJ = $(O)dlb.o
|
||||
|
||||
REGEX = $(O)cppregex.o
|
||||
|
||||
TTYOBJ = $(O)topl.o $(O)getline.o $(O)wintty.o
|
||||
TTYOBJ = $(O)topl.o $(O)getline.o $(O)wintty.o
|
||||
|
||||
MDLIB = $(O)mdlib.o
|
||||
|
||||
@@ -723,7 +723,7 @@ ccommon= -c -nologo -D"_CONSOLE" -D"_CRT_NONSTDC_NO_DEPRECATE" -D"_CRT_SECURE_NO
|
||||
-DHAS_STDINT_H -DHAS_INLINE $(CURSESDEF) $(RUNTIMEOPTDEF) \
|
||||
-EHsc -fp:precise -Gd -GF -GS -Gy \
|
||||
$(CL_RECENT) -WX- -Zc:forScope -Zc:wchar_t -Zi
|
||||
cdebug= -analyze- -D"_DEBUG" -MTd -RTC1 -Od
|
||||
cdebug= -analyze- -D"_DEBUG" -MTd -RTC1 -Od /fsanitize=address
|
||||
crelease= -analyze- -D"_MBCS" -errorReport:prompt -MT -O2 -Ot -Ox -Oy
|
||||
|
||||
lcommon= /NOLOGO /INCREMENTAL:NO
|
||||
@@ -2246,6 +2246,7 @@ $(TARGETPFX)track.o: track.c $(HACK_H)
|
||||
$(TARGETPFX)trap.o: trap.c $(HACK_H)
|
||||
$(TARGETPFX)u_init.o: u_init.c $(HACK_H)
|
||||
$(TARGETPFX)uhitm.o: uhitm.c $(HACK_H)
|
||||
$(TARGETPFX)utf8map.o: utf8map.c $(HACK_H)
|
||||
$(TARGETPFX)vault.o: vault.c $(HACK_H)
|
||||
$(TARGETPFX)version.o: version.c $(HACK_H) $(INCL)\dlb.h
|
||||
$(TARGETPFX)vision.o: vision.c $(HACK_H)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#ifndef NO_VT
|
||||
#define VIRTUAL_TERMINAL_SEQUENCES
|
||||
#define UTF8_FROM_CORE
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -84,6 +85,7 @@ typedef struct {
|
||||
WCHAR wcharacter;
|
||||
WORD attr;
|
||||
long color24;
|
||||
int color256idx;
|
||||
const char *colorseq;
|
||||
#endif /* VIRTUAL_TERMINAL_SEQUENCES */
|
||||
} cell_t;
|
||||
@@ -94,9 +96,9 @@ cell_t undefined_cell = { CONSOLE_UNDEFINED_CHARACTER,
|
||||
CONSOLE_UNDEFINED_ATTRIBUTE };
|
||||
#else /* VIRTUAL_TERMINAL_SEQUENCES */
|
||||
cell_t clear_cell = { { CONSOLE_CLEAR_CHARACTER, 0, 0, 0, 0, 0, 0 },
|
||||
CONSOLE_CLEAR_CHARACTER, 0, 0L, "\x1b[0m" };
|
||||
CONSOLE_CLEAR_CHARACTER, 0, 0L, 0, "\x1b[0m" };
|
||||
cell_t undefined_cell = { { CONSOLE_UNDEFINED_CHARACTER, 0, 0, 0, 0, 0, 0 },
|
||||
CONSOLE_UNDEFINED_CHARACTER, 0, 0L, (const char *) 0 };
|
||||
CONSOLE_UNDEFINED_CHARACTER, 0, 0L, 0, (const char *) 0 };
|
||||
static const uint8 empty_utf8str[MAX_UTF8_SEQUENCE] = { 0 };
|
||||
#endif /* VIRTUAL_TERMINAL_SEQUENCES */
|
||||
|
||||
@@ -137,7 +139,8 @@ static void restore_original_console_font(void);
|
||||
extern void safe_routines(void);
|
||||
void tty_ibmgraphics_fixup(void);
|
||||
#ifdef VIRTUAL_TERMINAL_SEQUENCES
|
||||
extern void (*ibmgraphics_mode_callback)(void); /* symbols.c */
|
||||
extern void (*ibmgraphics_mode_callback)(void); /* symbols.c */
|
||||
extern void (*utf8graphics_mode_callback)(void); /* symbols.c */
|
||||
#endif /* VIRTUAL_TERMINAL_SEQUENCES */
|
||||
|
||||
/* Win32 Screen buffer,coordinate,console I/O information */
|
||||
@@ -160,27 +163,9 @@ static boolean init_ttycolor_completed;
|
||||
#ifdef PORT_DEBUG
|
||||
static boolean display_cursor_info = FALSE;
|
||||
#endif
|
||||
#ifdef CHANGE_COLOR
|
||||
static void adjust_palette(void);
|
||||
static int match_color_name(const char *);
|
||||
typedef HWND(WINAPI *GETCONSOLEWINDOW)();
|
||||
static HWND GetConsoleHandle(void);
|
||||
static HWND GetConsoleHwnd(void);
|
||||
static boolean altered_palette;
|
||||
static COLORREF UserDefinedColors[CLR_MAX];
|
||||
static COLORREF NetHackColors[CLR_MAX] = {
|
||||
0x00000000, 0x00c80000, 0x0000c850, 0x00b4b432, 0x000000d2, 0x00800080,
|
||||
0x000064b4, 0x00c0c0c0, 0x00646464, 0x00f06464, 0x0000ff00, 0x00ffff00,
|
||||
0x000000ff, 0x00ff00ff, 0x0000ffff, 0x00ffffff
|
||||
};
|
||||
static COLORREF DefaultColors[CLR_MAX] = {
|
||||
0x00000000, 0x00800000, 0x00008000, 0x00808000, 0x00000080, 0x00800080,
|
||||
0x00008080, 0x00c0c0c0, 0x00808080, 0x00ff0000, 0x0000ff00, 0x00ffff00,
|
||||
0x000000ff, 0x00ff00ff, 0x0000ffff, 0x00ffffff
|
||||
};
|
||||
#endif
|
||||
struct console_t {
|
||||
boolean is_ready;
|
||||
HWND hWnd;
|
||||
WORD background;
|
||||
WORD foreground;
|
||||
WORD attr;
|
||||
@@ -217,8 +202,10 @@ struct console_t {
|
||||
DWORD in_cmode;
|
||||
DWORD out_cmode;
|
||||
long color24;
|
||||
int color256idx;
|
||||
} console = {
|
||||
FALSE,
|
||||
0,
|
||||
(FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED), /* background */
|
||||
(FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED), /* foreground */
|
||||
0, /* attr */
|
||||
@@ -263,7 +250,8 @@ struct console_t {
|
||||
NULL, /* localestr */
|
||||
0, /* in_cmode */
|
||||
0, /* out_cmode */
|
||||
0L /* color24 */
|
||||
0L, /* color24 */
|
||||
0 /* color256idx */
|
||||
#endif /* VIRTUAL_TERMINAL_SEQUENCES */
|
||||
};
|
||||
|
||||
@@ -532,6 +520,7 @@ void emit_stop_underline(void);
|
||||
void emit_start_inverse(void);
|
||||
void emit_stop_inverse(void);
|
||||
void emit_start_24bitcolor(long color24bit);
|
||||
void emit_start_256color(int u256coloridx);
|
||||
void emit_default_color(void);
|
||||
void emit_return_to_default(void);
|
||||
void emit_hide_cursor(void);
|
||||
@@ -656,22 +645,42 @@ emit_stop_inverse(void)
|
||||
&unused, &reserved);
|
||||
}
|
||||
|
||||
#if 0
|
||||
#define tcfmtstr "\x1b[38;2;%d;%d;%dm"
|
||||
#if 0
|
||||
#define tcfmtstr "\x1b[38:2:%d:%d:%dm"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SEP2
|
||||
#define tcfmtstr24bit "\x1b[38;2;%ld;%ld;%ldm"
|
||||
#define tcfmtstr256 "\x1b[38;5;%ldm"
|
||||
#else
|
||||
#define tcfmtstr24bit "\x1b[38:2:%ld:%ld:%ldm"
|
||||
#define tcfmtstr256 "\x1b[38:5:%dm"
|
||||
#endif
|
||||
|
||||
void
|
||||
emit_start_256color(int u256coloridx)
|
||||
{
|
||||
DWORD unused, reserved;
|
||||
static char tcolorbuf[QBUFSZ];
|
||||
Snprintf(tcolorbuf, sizeof tcolorbuf, tcfmtstr256, u256coloridx);
|
||||
WriteConsoleA(console.hConOut, (LPCSTR) tcolorbuf,
|
||||
(int) strlen(tcolorbuf), &unused, &reserved);
|
||||
}
|
||||
|
||||
void
|
||||
emit_start_24bitcolor(long color24bit)
|
||||
{
|
||||
DWORD unused, reserved;
|
||||
static char tcolorbuf[QBUFSZ];
|
||||
long mcolor24bit =
|
||||
long mcolor =
|
||||
(color24bit & 0xFFFFFF); /* color 0 has bit 0x1000000 set */
|
||||
Snprintf(tcolorbuf, sizeof tcolorbuf, tcfmtstr,
|
||||
((mcolor24bit >> 0) & 0xFF), /* red */
|
||||
((mcolor24bit >> 8) & 0xFF), /* green */
|
||||
((mcolor24bit >> 16) & 0xFF)); /* blue */
|
||||
Snprintf(tcolorbuf, sizeof tcolorbuf, tcfmtstr24bit,
|
||||
((mcolor >> 16) & 0xFF), /* red */
|
||||
((mcolor >> 8) & 0xFF), /* green */
|
||||
((mcolor >> 0) & 0xFF)); /* blue */
|
||||
WriteConsoleA(console.hConOut, (LPCSTR) tcolorbuf,
|
||||
(int) strlen(tcolorbuf), &unused, &reserved);
|
||||
}
|
||||
@@ -744,9 +753,19 @@ back_buffer_flip(void)
|
||||
do_anything |= do_colorseq;
|
||||
if (back->attr != front->attr)
|
||||
do_anything |= do_newattr;
|
||||
if (strcmp((const char *) back->utf8str,
|
||||
(const char *) front->utf8str))
|
||||
do_anything |= do_utf8_content;
|
||||
#ifdef UTF8_FROM_CORE
|
||||
if (!SYMHANDLING(H_UTF8)) {
|
||||
if (console.has_unicode
|
||||
&& (back->wcharacter != front->wcharacter))
|
||||
do_anything |= do_wide_content;
|
||||
} else {
|
||||
#endif
|
||||
if (strcmp((const char *) back->utf8str,
|
||||
(const char *) front->utf8str))
|
||||
do_anything |= do_utf8_content;
|
||||
#ifdef UTF8_FROM_CORE
|
||||
}
|
||||
#endif
|
||||
if (do_anything) {
|
||||
SetConsoleCursorPosition(console.hConOut, pos);
|
||||
pos_set = TRUE;
|
||||
@@ -771,7 +790,10 @@ back_buffer_flip(void)
|
||||
if (color24_on && back->color24) {
|
||||
did_anything |= did_color24;
|
||||
if (back->color24) {
|
||||
emit_start_24bitcolor(back->color24);
|
||||
if (!iflags.use_truecolor && iflags.colorcount == 256)
|
||||
emit_start_256color(back->color256idx);
|
||||
else
|
||||
emit_start_24bitcolor(back->color24);
|
||||
}
|
||||
} else if (back->colorseq) {
|
||||
did_anything |= did_colorseq;
|
||||
@@ -784,9 +806,20 @@ back_buffer_flip(void)
|
||||
}
|
||||
if (did_anything
|
||||
|| (do_anything & (do_wide_content | do_utf8_content))) {
|
||||
#ifdef UTF8_FROM_CORE
|
||||
if (SYMHANDLING(H_UTF8) || !console.has_unicode) {
|
||||
WriteConsoleA(console.hConOut, (LPCSTR) back->utf8str,
|
||||
(int) strlen((char *) back->utf8str),
|
||||
&unused, &reserved);
|
||||
did_anything |= did_utf8_content;
|
||||
} else {
|
||||
#endif
|
||||
WriteConsoleW(console.hConOut, &back->wcharacter, 1,
|
||||
&unused, &reserved);
|
||||
did_anything |= did_wide_content;
|
||||
#ifdef UTF8_FROM_CORE
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (did_anything) {
|
||||
@@ -930,10 +963,6 @@ settty(const char* s)
|
||||
void
|
||||
setftty()
|
||||
{
|
||||
#ifdef CHANGE_COLOR
|
||||
if (altered_palette)
|
||||
adjust_palette();
|
||||
#endif
|
||||
start_screen();
|
||||
}
|
||||
|
||||
@@ -943,6 +972,8 @@ tty_startup(int *wid, int *hgt)
|
||||
*wid = console.width;
|
||||
*hgt = console.height;
|
||||
set_option_mod_status("mouse_support", set_in_game);
|
||||
iflags.colorcount = 16777216;
|
||||
// iflags.colorcount = 256;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -958,6 +989,11 @@ tty_start_screen()
|
||||
tty_number_pad(1); /* make keypad send digits */
|
||||
#ifdef VIRTUAL_TERMINAL_SEQUENCES
|
||||
ibmgraphics_mode_callback = tty_ibmgraphics_fixup;
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
#ifdef UTF8_FROM_CORE
|
||||
utf8graphics_mode_callback = tty_utf8graphics_fixup;
|
||||
#endif
|
||||
#endif
|
||||
#endif /* VIRTUAL_TERMINAL_SEQUENCES */
|
||||
}
|
||||
|
||||
@@ -1234,13 +1270,25 @@ xputc_core(int ch)
|
||||
// if (console.color24)
|
||||
// __debugbreak();
|
||||
cell.color24 = 0L;
|
||||
cell.color256idx = 0;
|
||||
wch[1] = 0;
|
||||
if (console.has_unicode) {
|
||||
wch[0] = (ch >= 0 && ch < SIZE(console.cpMap)) ? console.cpMap[ch]
|
||||
: ch;
|
||||
#ifdef UTF8_FROM_CORE
|
||||
if (SYMHANDLING(H_UTF8)) {
|
||||
/* we have to convert it to UTF-8 for cell.utf8str */
|
||||
ccount = WideCharToMultiByte(
|
||||
CP_UTF8, 0, wch, -1, (char *) cell.utf8str,
|
||||
(int) sizeof cell.utf8str, NULL, NULL);
|
||||
} else {
|
||||
#endif
|
||||
/* store the wide version here also, so we don't slow
|
||||
down back_buffer_flip() with conversions */
|
||||
cell.wcharacter = wch[0];
|
||||
#ifdef UTF8_FROM_CORE
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
/* we can just use the UTF-8 utf8str field, since ascii is a
|
||||
single-byte representation of a small subset of unicode */
|
||||
@@ -1278,6 +1326,11 @@ xputc_core(int ch)
|
||||
* Overrides wintty.c function of the same name
|
||||
* for win32. It is used for glyphs only, not text.
|
||||
*/
|
||||
#ifdef UTF8_FROM_CORE
|
||||
/* See g_pututf8() for a corresponding UTF-8 sequence
|
||||
* version, rather than a single character.
|
||||
*/
|
||||
#endif
|
||||
void
|
||||
g_putch(int in_ch)
|
||||
{
|
||||
@@ -1308,12 +1361,24 @@ g_putch(int in_ch)
|
||||
cell.attr = console.attr;
|
||||
cell.colorseq = esc_seq_colors[console.current_nhcolor];
|
||||
cell.color24 = console.color24 ? console.color24 : 0L;
|
||||
cell.color256idx = 0;
|
||||
wch[1] = 0;
|
||||
if (console.has_unicode) {
|
||||
wch[0] = (ch >= 0 && ch < SIZE(console.cpMap)) ? console.cpMap[ch] : ch;
|
||||
#ifdef UTF8_FROM_CORE
|
||||
if (SYMHANDLING(H_UTF8)) {
|
||||
/* we have to convert it to UTF-8 for cell.utf8str */
|
||||
ccount = WideCharToMultiByte(
|
||||
CP_UTF8, 0, wch, -1, (char *) cell.utf8str,
|
||||
(int) sizeof cell.utf8str, NULL, NULL);
|
||||
} else {
|
||||
#endif
|
||||
/* store the wide version here also, so we don't slow
|
||||
down back_buffer_flip() with conversions */
|
||||
cell.wcharacter = wch[0];
|
||||
#ifdef UTF8_FROM_CORE
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
/* we can just use the UTF-8 utf8str field, since ascii is a
|
||||
single-byte representation of a small subset of unicode */
|
||||
@@ -1326,16 +1391,41 @@ g_putch(int in_ch)
|
||||
}
|
||||
|
||||
#ifdef VIRTUAL_TERMINAL_SEQUENCES
|
||||
#ifdef UTF8_FROM_CORE
|
||||
/*
|
||||
* Overrides wintty.c function of the same name
|
||||
* for win32. It is used for glyphs only, not text and
|
||||
* only when a UTF-8 sequence is involved for the
|
||||
* representation. Single character representations
|
||||
* use g_putch() instead.
|
||||
*/
|
||||
void
|
||||
term_start_24bitcolor(long color24bit)
|
||||
g_pututf8(uint8 *sequence)
|
||||
{
|
||||
console.color24 = color24bit; /* color 0 has bit 0x1000000 set */
|
||||
set_console_cursor(ttyDisplay->curx, ttyDisplay->cury);
|
||||
cell_t cell;
|
||||
cell.attr = console.attr;
|
||||
cell.colorseq = esc_seq_colors[console.current_nhcolor];
|
||||
cell.color24 = console.color24 ? console.color24 : 0L;
|
||||
cell.color256idx =console.color256idx ? console.color256idx : 0;
|
||||
Snprintf((char *) cell.utf8str, sizeof cell.utf8str, "%s",
|
||||
(char *) sequence);
|
||||
buffer_write(console.back_buffer, &cell, console.cursor);
|
||||
}
|
||||
#endif /* UTF8_FROM_CORE */
|
||||
|
||||
void
|
||||
term_start_24bitcolor(struct unicode_representation *uval)
|
||||
{
|
||||
console.color24 = uval->ucolor; /* color 0 has bit 0x1000000 set */
|
||||
console.color256idx = uval->u256coloridx;
|
||||
}
|
||||
|
||||
void
|
||||
term_end_24bitcolor(void)
|
||||
{
|
||||
console.color24 = 0L;
|
||||
console.color256idx = 0;
|
||||
}
|
||||
#endif /* VIRTUAL_TERMINAL_SEQUENCES */
|
||||
|
||||
@@ -1712,7 +1802,15 @@ consoletty_preference_update(const char* pref)
|
||||
#endif
|
||||
}
|
||||
if (stricmp(pref, "symset") == 0) {
|
||||
#ifdef UTF8_FROM_CORE
|
||||
if ((tty_procs.wincap2 & WC2_U_UTF8STR) && SYMHANDLING(H_UTF8)) {
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
tty_utf8graphics_fixup();
|
||||
#endif
|
||||
} else if ((tty_procs.wincap2 & WC2_U_UTF8STR) && SYMHANDLING(H_IBM)) {
|
||||
#else
|
||||
if (SYMHANDLING(H_IBM)) {
|
||||
#endif
|
||||
tty_ibmgraphics_fixup();
|
||||
}
|
||||
check_and_set_font();
|
||||
@@ -1720,6 +1818,70 @@ consoletty_preference_update(const char* pref)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef UTF8_FROM_CORE
|
||||
#ifdef VIRTUAL_TERMINAL_SEQUENCES
|
||||
/*
|
||||
* This is called when making the switch to a symset
|
||||
* with a UTF8 handler to allow any operating system
|
||||
* specific changes to be carried out.
|
||||
*/
|
||||
void
|
||||
tty_utf8graphics_fixup(void)
|
||||
{
|
||||
CONSOLE_FONT_INFOEX console_font_info;
|
||||
if ((tty_procs.wincap2 & WC2_U_UTF8STR) && SYMHANDLING(H_UTF8)) {
|
||||
if (!console.hConOut)
|
||||
console.hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
/* the locale */
|
||||
if (console.localestr)
|
||||
free(console.localestr);
|
||||
console.localestr = strdup(setlocale(LC_ALL, ".UTF8"));
|
||||
/* the code page */
|
||||
SetConsoleOutputCP(65001);
|
||||
console.code_page = GetConsoleOutputCP();
|
||||
/* the font */
|
||||
console_font_info.cbSize = sizeof(console_font_info);
|
||||
BOOL success = GetCurrentConsoleFontEx(console.hConOut, FALSE,
|
||||
&console_font_info);
|
||||
/* Try DejaVu Sans Mono for Powerline */
|
||||
wcscpy_s(console_font_info.FaceName,
|
||||
sizeof(console_font_info.FaceName)
|
||||
/ sizeof(console_font_info.FaceName[0]),
|
||||
L"DejaVu Sans Mono for Powerline");
|
||||
console_font_info.cbSize = sizeof(console_font_info);
|
||||
success = SetCurrentConsoleFontEx(console.hConOut, FALSE,
|
||||
&console_font_info);
|
||||
if (!success) {
|
||||
/* Next, try Lucida Console */
|
||||
wcscpy_s(console_font_info.FaceName,
|
||||
sizeof(console_font_info.FaceName)
|
||||
/ sizeof(console_font_info.FaceName[0]),
|
||||
L"Lucida Console");
|
||||
console_font_info.cbSize = sizeof(console_font_info);
|
||||
success = SetCurrentConsoleFontEx(console.hConOut, FALSE,
|
||||
&console_font_info);
|
||||
}
|
||||
nhassert(success);
|
||||
if (success) {
|
||||
console.font_info = console_font_info;
|
||||
console.font_changed = TRUE;
|
||||
}
|
||||
/* the console mode */
|
||||
GetConsoleMode(console.hConOut, &console.out_cmode);
|
||||
#if 1
|
||||
if ((console.out_cmode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == 0) {
|
||||
/* recognize escape sequences */
|
||||
console.out_cmode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||
SetConsoleMode(console.hConOut, console.out_cmode);
|
||||
}
|
||||
#else
|
||||
console.out_cmode &= ~ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* UTF8_FROM_CORE */
|
||||
|
||||
/*
|
||||
* This is called when making the switch to a symset
|
||||
* with an IBM handler to allow any operating system
|
||||
@@ -1836,400 +1998,6 @@ synch_cursor(void)
|
||||
really_move_cursor();
|
||||
}
|
||||
|
||||
#ifdef CHANGE_COLOR
|
||||
void
|
||||
tty_change_color(color_number, rgb, reverse)
|
||||
int color_number, reverse;
|
||||
long rgb;
|
||||
{
|
||||
/* Map NetHack color index to NT Console palette index */
|
||||
int idx, win32_color_number[] = {
|
||||
0, /* CLR_BLACK 0 */
|
||||
4, /* CLR_RED 1 */
|
||||
2, /* CLR_GREEN 2 */
|
||||
6, /* CLR_BROWN 3 */
|
||||
1, /* CLR_BLUE 4 */
|
||||
5, /* CLR_MAGENTA 5 */
|
||||
3, /* CLR_CYAN 6 */
|
||||
7, /* CLR_GRAY 7 */
|
||||
8, /* NO_COLOR 8 */
|
||||
12, /* CLR_ORANGE 9 */
|
||||
10, /* CLR_BRIGHT_GREEN 10 */
|
||||
14, /* CLR_YELLOW 11 */
|
||||
9, /* CLR_BRIGHT_BLUE 12 */
|
||||
13, /* CLR_BRIGHT_MAGENTA 13 */
|
||||
11, /* CLR_BRIGHT_CYAN 14 */
|
||||
15 /* CLR_WHITE 15 */
|
||||
};
|
||||
int k;
|
||||
if (color_number < 0) { /* indicates OPTIONS=palette with no value */
|
||||
/* copy the NetHack palette into UserDefinedColors */
|
||||
for (k = 0; k < CLR_MAX; k++)
|
||||
UserDefinedColors[k] = NetHackColors[k];
|
||||
} else if (color_number >= 0 && color_number < CLR_MAX) {
|
||||
if (!altered_palette) {
|
||||
/* make sure a full suite is available */
|
||||
for (k = 0; k < CLR_MAX; k++)
|
||||
UserDefinedColors[k] = DefaultColors[k];
|
||||
}
|
||||
idx = win32_color_number[color_number];
|
||||
UserDefinedColors[idx] = rgb;
|
||||
}
|
||||
altered_palette = TRUE;
|
||||
}
|
||||
|
||||
char *
|
||||
tty_get_color_string()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
int
|
||||
match_color_name(c)
|
||||
const char *c;
|
||||
{
|
||||
const struct others {
|
||||
int idx;
|
||||
const char *colorname;
|
||||
} othernames[] = {
|
||||
{ CLR_MAGENTA, "purple" },
|
||||
{ CLR_BRIGHT_MAGENTA, "bright purple" },
|
||||
{ NO_COLOR, "dark gray" },
|
||||
{ NO_COLOR, "dark grey" },
|
||||
{ CLR_GRAY, "grey" },
|
||||
};
|
||||
|
||||
int cnt;
|
||||
for (cnt = 0; cnt < CLR_MAX; ++cnt) {
|
||||
if (!strcmpi(c, c_obj_colors[cnt]))
|
||||
return cnt;
|
||||
}
|
||||
for (cnt = 0; cnt < SIZE(othernames); ++cnt) {
|
||||
if (!strcmpi(c, othernames[cnt].colorname))
|
||||
return othernames[cnt].idx;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 0 if badoption syntax
|
||||
*/
|
||||
int
|
||||
alternative_palette(op)
|
||||
char *op;
|
||||
{
|
||||
/*
|
||||
* palette:color-R-G-B
|
||||
* OPTIONS=palette:green-4-3-1, palette:0-0-0-0
|
||||
*/
|
||||
int fieldcnt, color_number, rgb, red, green, blue;
|
||||
char *fields[4], *cp;
|
||||
|
||||
if (!op) {
|
||||
change_color(-1, 0, 0); /* indicates palette option with
|
||||
no value meaning "load an entire
|
||||
hard-coded NetHack palette." */
|
||||
return 1;
|
||||
}
|
||||
|
||||
cp = fields[0] = op;
|
||||
for (fieldcnt = 1; fieldcnt < 4; ++fieldcnt) {
|
||||
cp = index(cp, '-');
|
||||
if (!cp)
|
||||
return 0;
|
||||
fields[fieldcnt] = cp;
|
||||
cp++;
|
||||
}
|
||||
for (fieldcnt = 1; fieldcnt < 4; ++fieldcnt) {
|
||||
*(fields[fieldcnt]) = '\0';
|
||||
++fields[fieldcnt];
|
||||
}
|
||||
rgb = 0;
|
||||
for (fieldcnt = 0; fieldcnt < 4; ++fieldcnt) {
|
||||
if (fieldcnt == 0 && isalpha(*(fields[0]))) {
|
||||
color_number = match_color_name(fields[0]);
|
||||
if (color_number == -1)
|
||||
return 0;
|
||||
} else {
|
||||
int dcount = 0, cval = 0;
|
||||
cp = fields[fieldcnt];
|
||||
if (*cp == '\\' && index("0123456789xXoO", cp[1])) {
|
||||
const char *dp, *hex = "00112233445566778899aAbBcCdDeEfF";
|
||||
|
||||
cp++;
|
||||
if (*cp == 'x' || *cp == 'X')
|
||||
for (++cp; (dp = index(hex, *cp)) && (dcount++ < 2); cp++)
|
||||
cval = (int) ((cval * 16) + (dp - hex) / 2);
|
||||
else if (*cp == 'o' || *cp == 'O')
|
||||
for (++cp; (index("01234567", *cp)) && (dcount++ < 3);
|
||||
cp++)
|
||||
cval = (cval * 8) + (*cp - '0');
|
||||
else
|
||||
return 0;
|
||||
} else {
|
||||
for (; *cp && (index("0123456789", *cp)) && (dcount++ < 3);
|
||||
cp++)
|
||||
cval = (cval * 10) + (*cp - '0');
|
||||
}
|
||||
switch (fieldcnt) {
|
||||
case 0:
|
||||
color_number = cval;
|
||||
break;
|
||||
case 1:
|
||||
red = cval;
|
||||
break;
|
||||
case 2:
|
||||
green = cval;
|
||||
break;
|
||||
case 3:
|
||||
blue = cval;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
rgb = RGB(red, green, blue);
|
||||
if (color_number >= 0 && color_number < CLR_MAX)
|
||||
change_color(color_number, rgb, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This uses an undocumented method to set console attributes
|
||||
* at runtime including console palette
|
||||
*
|
||||
* VOID WINAPI SetConsolePalette(COLORREF palette[16])
|
||||
*
|
||||
* Author: James Brown at www.catch22.net
|
||||
*
|
||||
* Set palette of current console.
|
||||
* Palette should be of the form:
|
||||
*
|
||||
* COLORREF DefaultColors[CLR_MAX] =
|
||||
* {
|
||||
* 0x00000000, 0x00800000, 0x00008000, 0x00808000,
|
||||
* 0x00000080, 0x00800080, 0x00008080, 0x00c0c0c0,
|
||||
* 0x00808080, 0x00ff0000, 0x0000ff00, 0x00ffff00,
|
||||
* 0x000000ff, 0x00ff00ff, 0x0000ffff, 0x00ffffff
|
||||
* };
|
||||
*/
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
/*
|
||||
* Structure to send console via WM_SETCONSOLEINFO
|
||||
*/
|
||||
typedef struct _CONSOLE_INFO {
|
||||
ULONG Length;
|
||||
COORD ScreenBufferSize;
|
||||
COORD WindowSize;
|
||||
ULONG WindowPosX;
|
||||
ULONG WindowPosY;
|
||||
|
||||
COORD FontSize;
|
||||
ULONG FontFamily;
|
||||
ULONG FontWeight;
|
||||
WCHAR FaceName[32];
|
||||
|
||||
ULONG CursorSize;
|
||||
ULONG FullScreen;
|
||||
ULONG QuickEdit;
|
||||
ULONG AutoPosition;
|
||||
ULONG InsertMode;
|
||||
|
||||
USHORT ScreenColors;
|
||||
USHORT PopupColors;
|
||||
ULONG HistoryNoDup;
|
||||
ULONG HistoryBufferSize;
|
||||
ULONG NumberOfHistoryBuffers;
|
||||
|
||||
COLORREF ColorTable[16];
|
||||
|
||||
ULONG CodePage;
|
||||
HWND Hwnd;
|
||||
|
||||
WCHAR ConsoleTitle[0x100];
|
||||
} CONSOLE_INFO;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
BOOL SetConsoleInfo(HWND hwndConsole, CONSOLE_INFO *pci);
|
||||
static void GetConsoleSizeInfo(CONSOLE_INFO *pci);
|
||||
VOID WINAPI SetConsolePalette(COLORREF crPalette[16]);
|
||||
|
||||
void
|
||||
adjust_palette(void)
|
||||
{
|
||||
SetConsolePalette(UserDefinedColors);
|
||||
altered_palette = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/* only in Win2k+ (use FindWindow for NT4) */
|
||||
/* HWND WINAPI GetConsoleWindow(); */
|
||||
|
||||
/* Undocumented console message */
|
||||
#define WM_SETCONSOLEINFO (WM_USER + 201)
|
||||
|
||||
VOID WINAPI
|
||||
SetConsolePalette(COLORREF palette[16])
|
||||
{
|
||||
CONSOLE_INFO ci = { sizeof(ci) };
|
||||
int i;
|
||||
HWND hwndConsole = GetConsoleHandle();
|
||||
|
||||
/* get current size/position settings rather than using defaults.. */
|
||||
GetConsoleSizeInfo(&ci);
|
||||
|
||||
/* set these to zero to keep current settings */
|
||||
ci.FontSize.X = 0; /* def = 8 */
|
||||
ci.FontSize.Y = 0; /* def = 12 */
|
||||
ci.FontFamily = 0; /* def = 0x30 = FF_MODERN|FIXED_PITCH */
|
||||
ci.FontWeight = 0; /* 0x400; */
|
||||
/* lstrcpyW(ci.FaceName, L"Terminal"); */
|
||||
ci.FaceName[0] = L'\0';
|
||||
|
||||
ci.CursorSize = 25;
|
||||
ci.FullScreen = FALSE;
|
||||
ci.QuickEdit = TRUE;
|
||||
ci.AutoPosition = 0x10000;
|
||||
ci.InsertMode = TRUE;
|
||||
ci.ScreenColors = MAKEWORD(0x7, 0x0);
|
||||
ci.PopupColors = MAKEWORD(0x5, 0xf);
|
||||
|
||||
ci.HistoryNoDup = FALSE;
|
||||
ci.HistoryBufferSize = 50;
|
||||
ci.NumberOfHistoryBuffers = 4;
|
||||
|
||||
// colour table
|
||||
for (i = 0; i < 16; i++)
|
||||
ci.ColorTable[i] = palette[i];
|
||||
|
||||
ci.CodePage = GetConsoleOutputCP();
|
||||
ci.Hwnd = hwndConsole;
|
||||
|
||||
lstrcpyW(ci.ConsoleTitle, L"");
|
||||
|
||||
SetConsoleInfo(hwndConsole, &ci);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper around WM_SETCONSOLEINFO. We need to create the
|
||||
* necessary section (file-mapping) object in the context of the
|
||||
* process which owns the console, before posting the message
|
||||
*/
|
||||
BOOL
|
||||
SetConsoleInfo(HWND hwndConsole, CONSOLE_INFO *pci)
|
||||
{
|
||||
DWORD dwConsoleOwnerPid;
|
||||
HANDLE hProcess;
|
||||
HANDLE hSection, hDupSection;
|
||||
PVOID ptrView = 0;
|
||||
HANDLE hThread;
|
||||
|
||||
/*
|
||||
* Open the process which "owns" the console
|
||||
*/
|
||||
GetWindowThreadProcessId(hwndConsole, &dwConsoleOwnerPid);
|
||||
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwConsoleOwnerPid);
|
||||
|
||||
/*
|
||||
* Create a SECTION object backed by page-file, then map a view of
|
||||
* this section into the owner process so we can write the contents
|
||||
* of the CONSOLE_INFO buffer into it
|
||||
*/
|
||||
hSection = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0,
|
||||
pci->Length, 0);
|
||||
|
||||
/*
|
||||
* Copy our console structure into the section-object
|
||||
*/
|
||||
ptrView = MapViewOfFile(hSection, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0,
|
||||
pci->Length);
|
||||
memcpy(ptrView, pci, pci->Length);
|
||||
UnmapViewOfFile(ptrView);
|
||||
|
||||
/*
|
||||
* Map the memory into owner process
|
||||
*/
|
||||
DuplicateHandle(GetCurrentProcess(), hSection, hProcess, &hDupSection, 0,
|
||||
FALSE, DUPLICATE_SAME_ACCESS);
|
||||
|
||||
/* Send console window the "update" message */
|
||||
SendMessage(hwndConsole, WM_SETCONSOLEINFO, (WPARAM) hDupSection, 0);
|
||||
|
||||
/*
|
||||
* clean up
|
||||
*/
|
||||
hThread = CreateRemoteThread(hProcess, 0, 0,
|
||||
(LPTHREAD_START_ROUTINE) CloseHandle,
|
||||
hDupSection, 0, 0);
|
||||
|
||||
CloseHandle(hThread);
|
||||
CloseHandle(hSection);
|
||||
CloseHandle(hProcess);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill the CONSOLE_INFO structure with information
|
||||
* about the current console window
|
||||
*/
|
||||
static void
|
||||
GetConsoleSizeInfo(CONSOLE_INFO *pci)
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
|
||||
HANDLE hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
GetConsoleScreenBufferInfo(hConsoleOut, &csbi);
|
||||
|
||||
pci->ScreenBufferSize = csbi.dwSize;
|
||||
pci->WindowSize.X = csbi.srWindow.Right - csbi.srWindow.Left + 1;
|
||||
pci->WindowSize.Y = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
|
||||
pci->WindowPosX = csbi.srWindow.Left;
|
||||
pci->WindowPosY = csbi.srWindow.Top;
|
||||
}
|
||||
|
||||
static HWND
|
||||
GetConsoleHandle(void)
|
||||
{
|
||||
HMODULE hMod = GetModuleHandle("kernel32.dll");
|
||||
GETCONSOLEWINDOW pfnGetConsoleWindow =
|
||||
(GETCONSOLEWINDOW) GetProcAddress(hMod, "GetConsoleWindow");
|
||||
if (pfnGetConsoleWindow)
|
||||
return pfnGetConsoleWindow();
|
||||
else
|
||||
return GetConsoleHwnd();
|
||||
}
|
||||
|
||||
static HWND
|
||||
GetConsoleHwnd(void)
|
||||
{
|
||||
int iterations = 0;
|
||||
HWND hwndFound = 0;
|
||||
char OldTitle[1024], NewTitle[1024], TestTitle[1024];
|
||||
|
||||
/* Get current window title */
|
||||
GetConsoleTitle(OldTitle, sizeof OldTitle);
|
||||
|
||||
(void) sprintf(NewTitle, "NETHACK%d/%d", GetTickCount(),
|
||||
GetCurrentProcessId());
|
||||
SetConsoleTitle(NewTitle);
|
||||
|
||||
GetConsoleTitle(TestTitle, sizeof TestTitle);
|
||||
while (strcmp(TestTitle, NewTitle) != 0) {
|
||||
iterations++;
|
||||
/* sleep(0); */
|
||||
GetConsoleTitle(TestTitle, sizeof TestTitle);
|
||||
}
|
||||
hwndFound = FindWindow(NULL, NewTitle);
|
||||
SetConsoleTitle(OldTitle);
|
||||
/* printf("%d iterations\n", iterations); */
|
||||
return hwndFound;
|
||||
}
|
||||
#endif /*CHANGE_COLOR*/
|
||||
|
||||
static int CALLBACK EnumFontCallback(
|
||||
const LOGFONTW * lf, const TEXTMETRICW * tm, DWORD fontType, LPARAM lParam)
|
||||
{
|
||||
@@ -2271,8 +2039,8 @@ check_font_widths(void)
|
||||
* NOTE: the DC from the console window does not have the correct
|
||||
* font selected at this point.
|
||||
*/
|
||||
HWND hWnd = GetConsoleWindow();
|
||||
HDC hDC = GetDC(hWnd);
|
||||
console.hWnd = GetConsoleWindow();
|
||||
HDC hDC = GetDC(console.hWnd);
|
||||
|
||||
LOGFONTW logical_font;
|
||||
logical_font.lfCharSet = DEFAULT_CHARSET;
|
||||
@@ -2574,6 +2342,14 @@ void nethack_enter_consoletty(void)
|
||||
#if 0
|
||||
/* set up state needed by early_raw_print() */
|
||||
windowprocs.win_raw_print = early_raw_print;
|
||||
#endif
|
||||
#if 0
|
||||
/* prevent re-sizing of the console window */
|
||||
if (!console.hWnd)
|
||||
console.hWnd = GetConsoleWindow();
|
||||
SetWindowLong(console.hWnd, GWL_STYLE,
|
||||
GetWindowLong(console.hWnd, GWL_STYLE)
|
||||
& ~WS_MAXIMIZEBOX & ~WS_SIZEBOX);
|
||||
#endif
|
||||
console.hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
nhassert(console.hConOut != NULL); // NOTE: this assert will not print
|
||||
|
||||
@@ -35,6 +35,16 @@ extern void backsp(void);
|
||||
#endif
|
||||
extern void clear_screen(void);
|
||||
|
||||
#if defined(TERMLIB) || defined(CURSES_GRAPHICS)
|
||||
extern void (*decgraphics_mode_callback)(void);
|
||||
#endif
|
||||
#ifdef CURSES_GRAPHICS
|
||||
extern void (*cursesgraphics_mode_callback)(void);
|
||||
#endif
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
extern void (*utf8graphics_mode_callback)(void);
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef kbhit
|
||||
#undef kbhit
|
||||
@@ -393,7 +403,8 @@ copy_hack_content()
|
||||
update_file(g.fqn_prefix[HACKPREFIX], OPTIONFILE,
|
||||
g.fqn_prefix[DATAPREFIX], OPTIONFILE, FALSE);
|
||||
}
|
||||
|
||||
extern const char *known_handling[]; /* symbols.c */
|
||||
extern const char *known_restrictions[]; /* symbols.c */
|
||||
/*
|
||||
* __MINGW32__ Note
|
||||
* If the graphics version is built, we don't need a main; it is skipped
|
||||
@@ -420,7 +431,7 @@ mingw_main(int argc, char *argv[])
|
||||
safe_routines();
|
||||
early_init();
|
||||
#ifdef _MSC_VER
|
||||
# ifdef DEBUG
|
||||
#ifdef DEBUG
|
||||
/* set these appropriately for VS debugging */
|
||||
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
|
||||
_CrtSetReportMode(_CRT_ERROR,
|
||||
@@ -439,7 +450,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
|
||||
| _CRTDBG_LEAK_CHECK_DF);
|
||||
_CrtSetBreakAlloc(1423);
|
||||
*/
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
g.hname = "NetHack"; /* used for syntax messages */
|
||||
@@ -480,7 +491,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
|
||||
}
|
||||
|
||||
/* Finished processing options, lock all directory paths */
|
||||
for(int i = 0; i < PREFIX_COUNT; i++)
|
||||
for (int i = 0; i < PREFIX_COUNT; i++)
|
||||
fqn_prefix_locked[i] = TRUE;
|
||||
|
||||
if (!validate_prefix_locations(failbuf)) {
|
||||
@@ -491,23 +502,23 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
|
||||
|
||||
copy_hack_content();
|
||||
|
||||
/*
|
||||
* It seems you really want to play.
|
||||
*/
|
||||
if (argc >= 1
|
||||
&& !strcmpi(default_window_sys, "mswin")
|
||||
/*
|
||||
* It seems you really want to play.
|
||||
*/
|
||||
if (argc >= 1 && !strcmpi(default_window_sys, "mswin")
|
||||
&& (strstri(argv[0], "nethackw.exe") || GUILaunched))
|
||||
iflags.windowtype_locked = TRUE;
|
||||
windowtype = default_window_sys;
|
||||
|
||||
#ifdef DLB
|
||||
if (!dlb_init()) {
|
||||
pline("%s\n%s\n%s\n%s\n\n",
|
||||
copyright_banner_line(1), copyright_banner_line(2),
|
||||
copyright_banner_line(3), copyright_banner_line(4));
|
||||
pline("NetHack was unable to open the required file \"%s\"",DLBFILE);
|
||||
pline("%s\n%s\n%s\n%s\n\n", copyright_banner_line(1),
|
||||
copyright_banner_line(2), copyright_banner_line(3),
|
||||
copyright_banner_line(4));
|
||||
pline("NetHack was unable to open the required file \"%s\"", DLBFILE);
|
||||
if (file_exists(DLBFILE))
|
||||
pline("\nAre you perhaps trying to run NetHack within a zip utility?");
|
||||
pline("\nAre you perhaps trying to run NetHack within a zip "
|
||||
"utility?");
|
||||
error("dlb_init failure.");
|
||||
}
|
||||
#endif
|
||||
@@ -540,6 +551,33 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
|
||||
if (WINDOWPORT("tty"))
|
||||
toggle_mouse_support();
|
||||
|
||||
if (g.symset[PRIMARYSET].handling
|
||||
&& !symset_is_compatible(g.symset[PRIMARYSET].handling,
|
||||
windowprocs.wincap2)) {
|
||||
/* current symset handling and windowtype are
|
||||
not compatible, feature-wise. Use IBM defaults */
|
||||
load_symset("IBMGraphics_2", PRIMARYSET);
|
||||
load_symset("RogueEpyx", ROGUESET);
|
||||
}
|
||||
/* Has the callback for the symset been invoked? Config file processing to
|
||||
load a symset runs too early to accomplish that because
|
||||
the various *graphics_mode_callback pointers don't get set until
|
||||
term_start_screen, unfortunately */
|
||||
#if defined(TERMLIB) || defined(CURSES_GRAPHICS)
|
||||
if (SYMHANDLING(H_DEC) && decgraphics_mode_callback)
|
||||
(*decgraphics_mode_callback)();
|
||||
#endif /* TERMLIB || CURSES */
|
||||
#if 0
|
||||
#ifdef CURSES_GRAPHICS
|
||||
if (WINDOWPORT("curses"))
|
||||
(*cursesgraphics_mode_callback)();
|
||||
#endif
|
||||
#endif
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if (SYMHANDLING(H_UTF8) && utf8graphics_mode_callback)
|
||||
(*utf8graphics_mode_callback)();
|
||||
#endif
|
||||
|
||||
/* strip role,race,&c suffix; calls askname() if g.plname[] is empty
|
||||
or holds a generic user name like "player" or "games" */
|
||||
plnamesuffix();
|
||||
@@ -656,7 +694,12 @@ process_options(int argc, char * argv[])
|
||||
#ifndef NODUMPENUMS
|
||||
if (argcheck(argc, argv, ARG_DUMPENUMS) == 2) {
|
||||
nethack_exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if (argcheck(argc, argv, ARG_DUMPGLYPHIDS) == 2) {
|
||||
nethack_exit(EXIT_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
if (argcheck(argc, argv, ARG_DEBUG) == 1) {
|
||||
argc--;
|
||||
|
||||
@@ -547,7 +547,7 @@ void NetHackQtMapViewport::PrintGlyph(int x, int y,
|
||||
{
|
||||
Glyph(x, y) = (unsigned short) glyphinfo->glyph;
|
||||
Glyphttychar(x, y) = (unsigned short) glyphinfo->ttychar;
|
||||
Glyphcolor(x, y) = (unsigned short) glyphinfo->gm.color;
|
||||
Glyphcolor(x, y) = (unsigned short) glyphinfo->gm.sym.color;
|
||||
Glyphflags(x, y) = glyphinfo->gm.glyphflags;
|
||||
Glyphtileidx(x, y) = (unsigned short) glyphinfo->gm.tileidx;
|
||||
Changed(x, y);
|
||||
|
||||
@@ -113,7 +113,7 @@ X11_print_glyph(
|
||||
register unsigned char *co_ptr;
|
||||
#endif
|
||||
|
||||
color = glyphinfo->gm.color;
|
||||
color = glyphinfo->gm.sym.color;
|
||||
special = glyphinfo->gm.glyphflags;
|
||||
och = glyphinfo->ttychar;
|
||||
ch = (uchar) och;
|
||||
|
||||
@@ -741,8 +741,8 @@ curses_init_options(void)
|
||||
set_option_mod_status("eight_bit_tty", set_in_config);
|
||||
|
||||
/* If we don't have a symset defined, load the curses symset by default */
|
||||
if (!g.symset[PRIMARY].explicitly)
|
||||
load_symset("curses", PRIMARY);
|
||||
if (!g.symset[PRIMARYSET].explicitly)
|
||||
load_symset("curses", PRIMARYSET);
|
||||
if (!g.symset[ROGUESET].explicitly)
|
||||
load_symset("default", ROGUESET);
|
||||
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
#include "hack.h"
|
||||
#include "color.h"
|
||||
#include "wincurs.h"
|
||||
#ifdef CURSES_UNICODE
|
||||
#include "locale.h"
|
||||
#endif
|
||||
|
||||
/* define this if not linking with <foo>tty.o|.obj for some reason */
|
||||
#ifdef CURSES_DEFINE_ERASE_CHAR
|
||||
@@ -41,6 +44,9 @@ struct window_procs curses_procs = {
|
||||
#endif
|
||||
| WC_PERM_INVENT | WC_POPUP_DIALOG | WC_SPLASH_SCREEN),
|
||||
(WC2_DARKGRAY | WC2_HITPOINTBAR
|
||||
#ifdef CURSES_UNICODE
|
||||
| WC2_U_UTF8STR
|
||||
#endif
|
||||
#ifdef SELECTSAVED
|
||||
| WC2_SELECTSAVED
|
||||
#endif
|
||||
@@ -150,6 +156,10 @@ curses_init_nhwindows(int *argcp UNUSED,
|
||||
char window_title[BUFSZ];
|
||||
#endif
|
||||
|
||||
#ifdef CURSES_UNICODE
|
||||
setlocale(LC_CTYPE, "");
|
||||
#endif
|
||||
|
||||
#ifdef XCURSES
|
||||
base_term = Xinitscr(*argcp, argv);
|
||||
#else
|
||||
@@ -760,7 +770,7 @@ curses_print_glyph(winid wid, xchar x, xchar y,
|
||||
glyph = glyphinfo->glyph;
|
||||
special = glyphinfo->gm.glyphflags;
|
||||
ch = glyphinfo->ttychar;
|
||||
color = glyphinfo->gm.color;
|
||||
color = glyphinfo->gm.sym.color;
|
||||
if ((special & MG_PET) && iflags.hilite_pet) {
|
||||
attr = iflags.wc2_petattr;
|
||||
}
|
||||
@@ -789,7 +799,17 @@ curses_print_glyph(winid wid, xchar x, xchar y,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if (SYMHANDLING(H_UTF8)
|
||||
&& glyphinfo->gm.u
|
||||
&& glyphinfo->gm.u->utf8str) {
|
||||
curses_putch(wid, x, y, ch, glyphinfo->gm.u, color, attr);
|
||||
} else {
|
||||
curses_putch(wid, x, y, ch, NULL, color, attr);
|
||||
}
|
||||
#else
|
||||
curses_putch(wid, x, y, ch, color, attr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -33,6 +33,7 @@ typedef struct nhchar {
|
||||
int ch; /* character */
|
||||
int color; /* color info for character */
|
||||
int attr; /* attributes of character */
|
||||
struct unicode_representation *unicode_representation;
|
||||
} nethack_char;
|
||||
|
||||
static boolean map_clipped; /* Map window smaller than 80x21 */
|
||||
@@ -363,7 +364,13 @@ curs_destroy_all_wins(void)
|
||||
/* Print a single character in the given window at the given coordinates */
|
||||
|
||||
void
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
curses_putch(winid wid, int x, int y, int ch,
|
||||
struct unicode_representation *unicode_representation,
|
||||
int color, int attr)
|
||||
#else
|
||||
curses_putch(winid wid, int x, int y, int ch, int color, int attr)
|
||||
#endif
|
||||
{
|
||||
static boolean map_initted = FALSE;
|
||||
int sx, sy, ex, ey;
|
||||
@@ -387,6 +394,9 @@ curses_putch(winid wid, int x, int y, int ch, int color, int attr)
|
||||
map[y][x].ch = ch;
|
||||
map[y][x].color = color;
|
||||
map[y][x].attr = attr;
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
map[y][x].unicode_representation = unicode_representation;
|
||||
#endif
|
||||
nch = map[y][x];
|
||||
|
||||
(void) curses_map_borders(&sx, &sy, &ex, &ey, -1, -1);
|
||||
@@ -589,7 +599,10 @@ write_char(WINDOW * win, int x, int y, nethack_char nch)
|
||||
#ifdef PDCURSES
|
||||
mvwaddrawch(win, y, x, nch.ch);
|
||||
#else
|
||||
mvwaddch(win, y, x, nch.ch);
|
||||
if (nch.unicode_representation && nch.unicode_representation->utf8str)
|
||||
mvwprintw(win, y, x, "%s", nch.unicode_representation->utf8str);
|
||||
else
|
||||
mvwaddch(win, y, x, nch.ch);
|
||||
#endif
|
||||
curses_toggle_color_attr(win, nch.color, nch.attr, OFF);
|
||||
}
|
||||
@@ -694,6 +707,7 @@ clear_map(void)
|
||||
map[y][x].ch = ' ';
|
||||
map[y][x].color = NO_COLOR;
|
||||
map[y][x].attr = A_NORMAL;
|
||||
map[y][x].unicode_representation = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,12 @@ void curses_refresh_nhwin(winid wid);
|
||||
void curses_del_nhwin(winid wid);
|
||||
void curses_del_wid(winid wid);
|
||||
void curs_destroy_all_wins(void);
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
void curses_putch(winid wid, int x, int y, int ch,
|
||||
struct unicode_representation *ur, int color, int attrs);
|
||||
#else
|
||||
void curses_putch(winid wid, int x, int y, int ch, int color, int attrs);
|
||||
#endif
|
||||
void curses_get_window_xy(winid wid, int *x, int *y);
|
||||
boolean curses_window_has_border(winid wid);
|
||||
boolean curses_window_exists(winid wid);
|
||||
|
||||
@@ -1341,22 +1341,32 @@ main(int argc UNUSED, char *argv[] UNUSED)
|
||||
Fprintf(ofp, "int maxmontile = %d,\n", lastmontile);
|
||||
Fprintf(ofp, "%smaxobjtile = %d,\n", indent, lastobjtile);
|
||||
Fprintf(ofp, "%smaxothtile = %d;\n\n", indent, lastothtile);
|
||||
Fprintf(ofp,
|
||||
"/* glyph, ttychar, { color, symidx, ovidx, glyphflags, tileidx} */\n");
|
||||
Fprintf(ofp,
|
||||
"/* glyph, ttychar, { glyphflags, {color, symidx}, ovidx, tileidx, 0 } */\n");
|
||||
Fprintf(ofp, "const glyph_info nul_glyphinfo = { \n");
|
||||
Fprintf(ofp, "%sNO_GLYPH, ' ',\n", indent);
|
||||
Fprintf(ofp, "%s%s{ /* glyph_map */\n", indent, indent);
|
||||
Fprintf(ofp, "%s%s%sNO_COLOR, SYM_UNEXPLORED + SYM_OFF_X,\n",
|
||||
Fprintf(ofp, "%s%s%sMG_UNEXPL, { NO_COLOR, SYM_UNEXPLORED + SYM_OFF_X },\n",
|
||||
indent, indent, indent);
|
||||
Fprintf(ofp, "%s%s%sMG_UNEXPL, %d\n", indent, indent, indent,
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
Fprintf(ofp, "%s%s%s%d, 0\n", indent, indent, indent,
|
||||
TILE_unexplored);
|
||||
#else
|
||||
Fprintf(ofp, "%s%s%s%d\n", indent, indent, indent,
|
||||
TILE_unexplored);
|
||||
#endif
|
||||
Fprintf(ofp, "%s%s}\n", indent, indent);
|
||||
Fprintf(ofp, "};\n");
|
||||
Fprintf(ofp, "\nglyph_map glyphmap[MAX_GLYPH] = {\n");
|
||||
|
||||
for (i = 0; i < MAX_GLYPH; i++) {
|
||||
tilenum = tilemap[i].tilenum;
|
||||
Fprintf(ofp, " { 0, 0, 0U, %4d }, /* [%04d] %s=%03d %s */\n",
|
||||
Fprintf(ofp,
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
" { 0U, { 0, 0 }, %4d, 0 }, /* [%04d] %s:%03d %s */\n",
|
||||
#else
|
||||
" { 0U, { 0, 0 }, %4d}, /* [%04d] %s:%03d %s */\n",
|
||||
#endif
|
||||
tilenum, i,
|
||||
tilesrc_texts[tilelist[tilenum]->src],
|
||||
tilelist[tilenum]->file_entry,
|
||||
|
||||
@@ -17,6 +17,9 @@ static char *e_atr2str(int);
|
||||
|
||||
void cmov(int, int);
|
||||
void nocmov(int, int);
|
||||
void term_start_24bitcolor(struct unicode_representation *);
|
||||
void term_end_24bitcolor(void);
|
||||
|
||||
#if defined(TEXTCOLOR) && defined(TERMLIB)
|
||||
#if (!defined(UNIX) || !defined(TERMINFO)) && !defined(TOS)
|
||||
static void analyze_seq(char *, int *, int *);
|
||||
@@ -430,11 +433,12 @@ tty_decgraphics_termcap_fixup(void)
|
||||
#endif /* TERMLIB */
|
||||
|
||||
#if defined(ASCIIGRAPH) && defined(PC9800)
|
||||
extern void (*ibmgraphics_mode_callback)(void); /* defined in drawing.c */
|
||||
extern void (*ibmgraphics_mode_callback)(void); /* defined in symbols.c */
|
||||
#endif
|
||||
extern void (*utf8graphics_mode_callback)(void); /* defined in symbols.c */
|
||||
|
||||
#ifdef PC9800
|
||||
extern void (*ascgraphics_mode_callback)(void); /* defined in drawing.c */
|
||||
extern void (*ascgraphics_mode_callback)(void); /* defined in symbols.c */
|
||||
static void tty_ascgraphics_hilite_fixup(void);
|
||||
|
||||
static void
|
||||
@@ -478,6 +482,10 @@ tty_start_screen(void)
|
||||
/* set up callback in case option is not set yet but toggled later */
|
||||
decgraphics_mode_callback = tty_decgraphics_termcap_fixup;
|
||||
#endif
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
utf8graphics_mode_callback = tty_utf8graphics_fixup;
|
||||
#endif
|
||||
|
||||
if (g.Cmd.num_pad)
|
||||
tty_number_pad(1); /* make keypad send digits */
|
||||
}
|
||||
@@ -870,14 +878,21 @@ const struct {
|
||||
{ COLOR_MAGENTA, CLR_MAGENTA, CLR_BRIGHT_MAGENTA },
|
||||
{ COLOR_CYAN, CLR_CYAN, CLR_BRIGHT_CYAN } };
|
||||
|
||||
typedef struct {
|
||||
unsigned char r, g, b;
|
||||
} RGB;
|
||||
|
||||
static char nilstring[] = "";
|
||||
|
||||
static void
|
||||
init_hilite(void)
|
||||
{
|
||||
int c, colors;
|
||||
char *setf, *scratch;
|
||||
int c, md_len = 0;
|
||||
int colors = tgetnum("Co");
|
||||
|
||||
colors = tgetnum("Co");
|
||||
iflags.colorcount = colors;
|
||||
int md_len = 0;
|
||||
|
||||
if (colors < 8 || (MD == NULL) || (strlen(MD) == 0)
|
||||
|| ((setf = tgetstr("AF", (char **) 0)) == (char *) 0
|
||||
@@ -1410,9 +1425,66 @@ term_start_color(int color)
|
||||
if (color < CLR_MAX && hilites[color] && *hilites[color])
|
||||
xputs(hilites[color]);
|
||||
}
|
||||
|
||||
#endif /* TEXTCOLOR */
|
||||
|
||||
#endif /* TTY_GRAPHICS && !NO_TERMS */
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
|
||||
#ifndef SEP2
|
||||
#define tcfmtstr "\033[38;2;%ld;%ld;%ldm"
|
||||
#ifdef UNIX
|
||||
#define tcfmtstr24bit "\033[38;2;%u;%u;%um"
|
||||
#define tcfmtstr256 "\033[38;5;%dm"
|
||||
#else
|
||||
#define tcfmtstr "\033[38:2:%ld:%ld:%ldm"
|
||||
#define tcfmtstr24bit "\033[38;2;%lu;%lu;%lum"
|
||||
#define tcfmtstr256 "\033[38:5:%ldm"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void emit24bit(long mcolor);
|
||||
static void emit256(int u256coloridx);
|
||||
|
||||
static void emit24bit(long mcolor)
|
||||
{
|
||||
static char tcolorbuf[QBUFSZ];
|
||||
|
||||
Snprintf(tcolorbuf, sizeof tcolorbuf, tcfmtstr,
|
||||
((mcolor >> 16) & 0xFF), /* red */
|
||||
((mcolor >> 8) & 0xFF), /* green */
|
||||
((mcolor >> 0) & 0xFF)); /* blue */
|
||||
xputs(tcolorbuf);
|
||||
}
|
||||
|
||||
static void emit256(int u256coloridx)
|
||||
{
|
||||
static char tcolorbuf[QBUFSZ];
|
||||
|
||||
Snprintf(tcolorbuf, sizeof tcolorbuf, tcfmtstr256,
|
||||
u256coloridx);
|
||||
xputs(tcolorbuf);
|
||||
}
|
||||
|
||||
void
|
||||
term_start_24bitcolor(struct unicode_representation *urep)
|
||||
{
|
||||
if (urep && SYMHANDLING(H_UTF8)) {
|
||||
/* color 0 has bit 0x1000000 set */
|
||||
long mcolor = (urep->ucolor & 0xFFFFFF);
|
||||
if (iflags.colorcount == 256)
|
||||
emit256(urep->u256coloridx);
|
||||
else
|
||||
emit24bit(mcolor);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
term_end_24bitcolor(void)
|
||||
{
|
||||
if (SYMHANDLING(H_UTF8)) {
|
||||
xputs("\033[0m");
|
||||
}
|
||||
}
|
||||
#endif /* ENHANCED_SYMBOLS */
|
||||
#endif /* TTY_GRAPHICS && !NO_TERMS */
|
||||
|
||||
/*termcap.c*/
|
||||
|
||||
@@ -124,13 +124,15 @@ redotoplin(const char *str)
|
||||
int otoplin = ttyDisplay->toplin;
|
||||
|
||||
home();
|
||||
if (*str & 0x80) {
|
||||
/* kludge for the / command, the only time we ever want a */
|
||||
/* graphics character on the top line */
|
||||
g_putch((int) *str++);
|
||||
ttyDisplay->curx++;
|
||||
if (!ttyDisplay->topl_utf8) {
|
||||
if (*str & 0x80) {
|
||||
/* kludge for the / command, the only time we ever want a */
|
||||
/* graphics character on the top line */
|
||||
g_putch((int) *str++);
|
||||
ttyDisplay->curx++;
|
||||
}
|
||||
end_glyphout(); /* in case message printed during graphics output */
|
||||
}
|
||||
end_glyphout(); /* in case message printed during graphics output */
|
||||
putsyms(str);
|
||||
cl_end();
|
||||
ttyDisplay->toplin = TOPLINE_NEED_MORE;
|
||||
|
||||
142
win/tty/wintty.c
142
win/tty/wintty.c
@@ -97,7 +97,7 @@ struct window_procs tty_procs = {
|
||||
#ifdef MSDOS
|
||||
| WC_TILED_MAP | WC_ASCII_MAP
|
||||
#endif
|
||||
#if defined(WIN32CON)
|
||||
#if defined(WIN32)
|
||||
| WC_MOUSE_SUPPORT
|
||||
#endif
|
||||
| WC_COLOR | WC_HILITE_PET | WC_INVERSE | WC_EIGHT_BIT_IN),
|
||||
@@ -109,7 +109,12 @@ struct window_procs tty_procs = {
|
||||
| WC2_HILITE_STATUS | WC2_HITPOINTBAR | WC2_FLUSH_STATUS
|
||||
| WC2_RESET_STATUS
|
||||
#endif
|
||||
| WC2_DARKGRAY | WC2_SUPPRESS_HIST | WC2_URGENT_MESG | WC2_STATUSLINES),
|
||||
| WC2_DARKGRAY | WC2_SUPPRESS_HIST | WC2_URGENT_MESG | WC2_STATUSLINES)
|
||||
| WC2_U_UTF8STR
|
||||
#if !defined(NO_TERMS) || defined(WIN32)
|
||||
| WC2_U_24BITCOLOR
|
||||
#endif
|
||||
,
|
||||
#ifdef TEXTCOLOR
|
||||
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
|
||||
#else
|
||||
@@ -118,7 +123,8 @@ struct window_procs tty_procs = {
|
||||
tty_init_nhwindows, tty_player_selection, tty_askname, tty_get_nh_event,
|
||||
tty_exit_nhwindows, tty_suspend_nhwindows, tty_resume_nhwindows,
|
||||
tty_create_nhwindow, tty_clear_nhwindow, tty_display_nhwindow,
|
||||
tty_destroy_nhwindow, tty_curs, tty_putstr, genl_putmixed,
|
||||
tty_destroy_nhwindow, tty_curs, tty_putstr,
|
||||
tty_putmixed,
|
||||
tty_display_file, tty_start_menu, tty_add_menu, tty_end_menu,
|
||||
tty_select_menu, tty_message_menu, tty_update_inventory, tty_mark_synch,
|
||||
tty_wait_synch,
|
||||
@@ -159,6 +165,7 @@ struct DisplayDesc *ttyDisplay; /* the tty display descriptor */
|
||||
|
||||
extern void cmov(int, int); /* from termcap.c */
|
||||
extern void nocmov(int, int); /* from termcap.c */
|
||||
|
||||
#if defined(UNIX) || defined(VMS)
|
||||
static char obuf[BUFSIZ]; /* BUFSIZ is defined in stdio.h */
|
||||
#endif
|
||||
@@ -231,6 +238,9 @@ static void shrink_dlvl(int);
|
||||
static void status_sanity_check(void);
|
||||
#endif /* NH_DEVEL_STATUS */
|
||||
#endif
|
||||
#if !defined(NO_TERMS) && !defined(WIN32)
|
||||
void g_pututf8(uint8 *utf8str);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A string containing all the default commands -- to add to a list
|
||||
@@ -442,6 +452,7 @@ tty_init_nhwindows(int *argcp UNUSED, char **argv UNUSED)
|
||||
/* set up tty descriptor */
|
||||
ttyDisplay = (struct DisplayDesc *) alloc(sizeof (struct DisplayDesc));
|
||||
ttyDisplay->toplin = TOPLINE_EMPTY;
|
||||
ttyDisplay->topl_utf8 = 0; /* putmixed may set this */
|
||||
ttyDisplay->rows = hgt;
|
||||
ttyDisplay->cols = wid;
|
||||
ttyDisplay->curx = ttyDisplay->cury = 0;
|
||||
@@ -2344,9 +2355,14 @@ process_text_window(winid window, struct WinDesc *cw)
|
||||
) {
|
||||
/* message recall for msg_window:full/combination/reverse
|
||||
might have output from '/' in it (see redotoplin()) */
|
||||
if (linestart && (*cp & 0x80) != 0) {
|
||||
g_putch(*cp);
|
||||
end_glyphout();
|
||||
if (linestart) {
|
||||
if (SYMHANDLING(H_UTF8)) {
|
||||
/* FIXME: what is actually in that line? is it the \GNNNNNNNN or UTF-8? */
|
||||
g_putch(*cp);
|
||||
} else if ((*cp & 0x80) != 0) {
|
||||
g_putch(*cp);
|
||||
end_glyphout();
|
||||
}
|
||||
linestart = FALSE;
|
||||
} else {
|
||||
(void) putchar(*cp);
|
||||
@@ -3367,8 +3383,11 @@ g_putch(int in_ch)
|
||||
register char ch = (char) in_ch;
|
||||
|
||||
HUPSKIP();
|
||||
|
||||
#if defined(ASCIIGRAPH) && !defined(NO_TERMS)
|
||||
if (SYMHANDLING(H_IBM)
|
||||
if (SYMHANDLING(H_UTF8)) {
|
||||
(void) putchar(ch);
|
||||
} else if (SYMHANDLING(H_IBM)
|
||||
/* for DECgraphics, lower-case letters with high bit set mean
|
||||
switch character set and render with high bit clear;
|
||||
user might want 8-bits for other characters */
|
||||
@@ -3397,6 +3416,17 @@ g_putch(int in_ch)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
g_pututf8(uint8 *utf8str)
|
||||
{
|
||||
HUPSKIP();
|
||||
while (*utf8str) {
|
||||
(void) putchar(*utf8str);
|
||||
utf8str++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif /* !WIN32 */
|
||||
|
||||
#ifdef CLIPPING
|
||||
@@ -3458,6 +3488,11 @@ tty_print_glyph(winid window, xchar x, xchar y,
|
||||
boolean inverse_on = FALSE;
|
||||
int ch, color;
|
||||
unsigned special;
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
#if !defined(NO_TERMS) || defined(WIN32)
|
||||
boolean color24bit_on = FALSE;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
HUPSKIP();
|
||||
#ifdef CLIPPING
|
||||
@@ -3468,7 +3503,7 @@ tty_print_glyph(winid window, xchar x, xchar y,
|
||||
#endif
|
||||
/* get glyph ttychar, color, and special flags */
|
||||
ch = glyphinfo->ttychar;
|
||||
color = glyphinfo->gm.color;
|
||||
color = glyphinfo->gm.sym.color;
|
||||
special = glyphinfo->gm.glyphflags;
|
||||
|
||||
print_vt_code2(AVTC_SELECT_WINDOW, window);
|
||||
@@ -3484,24 +3519,33 @@ tty_print_glyph(winid window, xchar x, xchar y,
|
||||
backsp();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (iflags.use_color) {
|
||||
#ifdef TEXTCOLOR
|
||||
if (iflags.wizmgender && (special & MG_FEMALE) && iflags.use_inverse) {
|
||||
if (ttyDisplay->color != NO_COLOR)
|
||||
term_end_color();
|
||||
term_start_attr(ATR_INVERSE);
|
||||
inverse_on = TRUE;
|
||||
ttyDisplay->color = CLR_RED;
|
||||
term_start_color(ttyDisplay->color);
|
||||
} else if (color != ttyDisplay->color) {
|
||||
if (ttyDisplay->color != NO_COLOR)
|
||||
term_end_color();
|
||||
ttyDisplay->color = color;
|
||||
if (color != NO_COLOR)
|
||||
term_start_color(color);
|
||||
}
|
||||
if (color != ttyDisplay->color) {
|
||||
if (ttyDisplay->color != NO_COLOR)
|
||||
term_end_color();
|
||||
}
|
||||
#endif
|
||||
#if !defined(NO_TERMS) || defined(WIN32)
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
/* we don't link with termcap.o if NO_TERMS is defined */
|
||||
if ((tty_procs.wincap2 & WC2_U_24BITCOLOR) && SYMHANDLING(H_UTF8)
|
||||
&& glyphinfo->gm.u && glyphinfo->gm.u->ucolor) {
|
||||
term_start_24bitcolor(glyphinfo->gm.u);
|
||||
color24bit_on = TRUE;
|
||||
} else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
#ifdef TEXTCOLOR
|
||||
ttyDisplay->color = color;
|
||||
if (color != NO_COLOR)
|
||||
term_start_color(color);
|
||||
#endif /* TEXTCOLOR */
|
||||
|
||||
#if !defined(NO_TERMS) || defined(WIN32)
|
||||
}
|
||||
#endif
|
||||
} /* iflags.use_color aka iflags.wc_color */
|
||||
/* must be after color check; term_end_color may turn off inverse too;
|
||||
BW_LAVA and BW_ICE won't ever be set when color is on;
|
||||
(tried bold for ice but it didn't look very good; inverse is easier
|
||||
@@ -3519,21 +3563,34 @@ tty_print_glyph(winid window, xchar x, xchar y,
|
||||
xputg(glyphinfo);
|
||||
else
|
||||
#endif
|
||||
g_putch(ch); /* print the character */
|
||||
|
||||
if (inverse_on) {
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if ((tty_procs.wincap2 & WC2_U_UTF8STR) && SYMHANDLING(H_UTF8)
|
||||
&& glyphinfo->gm.u && glyphinfo->gm.u->utf8str) {
|
||||
/* we have a sequence to do */
|
||||
g_pututf8(glyphinfo->gm.u->utf8str);
|
||||
} else
|
||||
#endif
|
||||
g_putch(ch); /* print the character */
|
||||
|
||||
if (inverse_on)
|
||||
term_end_attr(ATR_INVERSE);
|
||||
if (iflags.use_color) {
|
||||
#ifdef TEXTCOLOR
|
||||
/* turn off color as well, turning off ATR_INVERSE may have done
|
||||
this already and if so, we won't know the current state unless
|
||||
we do it explicitly */
|
||||
this already and if so, we won't know the current state unless
|
||||
we do it explicitly */
|
||||
if (ttyDisplay->color != NO_COLOR) {
|
||||
term_end_color();
|
||||
ttyDisplay->color = NO_COLOR;
|
||||
}
|
||||
#endif
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
#if !defined(NO_TERMS) || defined(WIN32)
|
||||
if (color24bit_on)
|
||||
term_end_24bitcolor();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
print_vt_code1(AVTC_GLYPH_END);
|
||||
|
||||
wins[window]->curx++; /* one character over */
|
||||
@@ -3688,6 +3745,31 @@ tty_update_positionbar(char *posbar)
|
||||
}
|
||||
#endif /* POSITIONBAR */
|
||||
|
||||
void
|
||||
tty_putmixed(winid window, int attr, const char *str)
|
||||
{
|
||||
struct WinDesc *cw;
|
||||
char buf[BUFSZ];
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
int utf8flag = 0;
|
||||
#endif
|
||||
|
||||
if (window == WIN_ERR || (cw = wins[window]) == (struct WinDesc *) 0) {
|
||||
tty_raw_print(str);
|
||||
return;
|
||||
}
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if ((windowprocs.wincap2 & WC2_U_UTF8STR) && SYMHANDLING(H_UTF8)) {
|
||||
mixed_to_utf8(buf, sizeof buf, str, &utf8flag);
|
||||
if (cw->type == NHW_MESSAGE)
|
||||
ttyDisplay->topl_utf8 = utf8flag;
|
||||
} else
|
||||
#endif
|
||||
decode_mixed(buf, str);
|
||||
/* now send it to the normal tty_putstr */
|
||||
tty_putstr(window, attr, buf);
|
||||
ttyDisplay->topl_utf8 = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* +------------------+
|
||||
|
||||
@@ -930,7 +930,7 @@ paintGlyph(PNHMapWindow data, int i, int j, RECT * rect)
|
||||
OldFg = SetTextColor(hDC, nhcolor_to_RGB(color));
|
||||
#else
|
||||
ch = (char) data->map[i][j].ttychar;
|
||||
color = (int) data->map[i][j].gm.color;
|
||||
color = (int) data->map[i][j].gm.sym.color;
|
||||
if (((data->map[i][j].gm.glyphflags & MG_PET) && iflags.hilite_pet)
|
||||
|| ((data->map[i][j].gm.glyphflags & (MG_DETECT | MG_BW_LAVA))
|
||||
&& iflags.use_inverse)) {
|
||||
@@ -1000,7 +1000,7 @@ static void setGlyph(PNHMapWindow data, int i, int j,
|
||||
if ((data->map[i][j].glyph != fg->glyph)
|
||||
|| (data->bkmap[i][j].glyph != bg->glyph)
|
||||
|| data->map[i][j].ttychar != fg->ttychar
|
||||
|| data->map[i][j].gm.color != fg->gm.color
|
||||
|| data->map[i][j].gm.sym.color != fg->gm.sym.color
|
||||
|| data->map[i][j].gm.glyphflags != fg->gm.glyphflags
|
||||
|| data->map[i][j].gm.tileidx != fg->gm.tileidx) {
|
||||
data->map[i][j] = *fg;
|
||||
|
||||
Reference in New Issue
Block a user