drawing overhaul (trunk only)

This is an overhaul to the NetHack drawing mechanism.

- eliminates the need to have separate lists in drawing.c
for the things and their associated explanations by grouping
those thing together on the same inializer in a struct.

- replaces all of these options: IBMgraphics, DECgraphics, MACgraphics,
graphics, monsters, objects, boulder, traps, effects

- drawing.c contains only the set of NetHack standard symbols for
the main game and a set of NetHack standard symbols for the
roguelevel.

- introduces a symbols file that contains named sets of
symbols that can be loaded at run time making it extensible
for situations like multinational code pages like those reported
by <Someone>, without hardcoding additional sets into the game code.

- symbols file uses names for the symbols, so offsets will not break
when new things are introduced into the game, the way the older
config file uchar load routines did.

- symbols file only contains exceptions to the standard NetHack
set, not entire sets so they are much less verbose than all of
the g_FILLER() entries that were previously in drawing.c

- 'symset' and 'roguesymset' config file options for
preselecting a symbol set from the file called 'symbols'
at startup time. The name of the symbols file is not under the
users control, only the symbol set name desired from within the
symbols file is.

- 'symset' config file option loads a desired symbol set for
everything but the rogue level.

- 'roguesymset' config file option loads a desired symbol set
for the rogue level.

- 'SYMBOLS' config file option allows the user to specify replacement
symbols on a per symbol basis. You can specify as many or as few symbols
as you wish. The symbols are identified by a name:value pair, and line
continuation is supported. Multiple symbol assignments can be made on
the same line if each name:value pair is separated by a comma.
For example:
SYMBOLS = S_bars:\xf0, S_tree: \xf1, S_room:\xfa \
	  S_fountain:\xf4 \
	  S_boulder:0

- 'symbols' file has the following structure:
start: DECgraphics
	Handling: DEC
	S_vwall: \xf8			# meta-x, vertical rule
	S_hwall: \xf1			# meta-q, horizontal rule
finish
start: IBMgraphics
	Handling: IBM
	S_vwall: \xb3			# meta-3, vertical rule
	S_hwall: \xc4			# meta-D, horizontal rule
finish

- 'symbols' file added to the source tree in the dat directory

- Port Makefiles/scripts will need to be adjusted to move them into
HACKDIR destination
This commit is contained in:
nethack.allison
2006-09-21 01:46:15 +00:00
parent 94b66d0be5
commit 253bf359af
39 changed files with 1859 additions and 1339 deletions

View File

@@ -425,14 +425,14 @@ int class; /* an object class, 0 for all */
* detect. Rather than trump anything, show both possibilities.
* We can exclude checking the buried obj chain for boulders below.
*/
sym = class ? def_oc_syms[class] : 0;
sym = class ? def_oc_syms[class].sym : 0;
if (sym && iflags.bouldersym && sym == iflags.bouldersym)
boulder = ROCK_CLASS;
if (Hallucination || (Confusion && class == SCROLL_CLASS))
Strcpy(stuff, something);
else
Strcpy(stuff, class ? oclass_names[class] : "objects");
Strcpy(stuff, class ? def_oc_syms[class].name : "objects");
if (boulder && class != ROCK_CLASS) Strcat(stuff, " and/or large stones");
if (do_dknown) for(obj = invent; obj; obj = obj->nobj) do_dknown_of(obj);
@@ -616,7 +616,7 @@ int mclass; /* monster class, 0 for all */
if (!mclass || mtmp->data->mlet == mclass ||
(mtmp->data == &mons[PM_LONG_WORM] && mclass == S_WORM_TAIL))
if (mtmp->mx > 0) {
if (mclass && def_monsyms[mclass] == ' ')
if (mclass && def_monsyms[mclass].sym == ' ')
show_glyph(mtmp->mx,mtmp->my,
detected_mon_to_glyph(mtmp));
else
@@ -917,7 +917,7 @@ struct obj *obj;
if (flags.verbose) You("may look for an object or monster symbol.");
ch = yn_function("What do you look for?", (char *)0, '\0');
/* Don't filter out ' ' here; it has a use */
if ((ch != def_monsyms[S_GHOST]) && index(quitchars,ch)) {
if ((ch != def_monsyms[S_GHOST].sym) && index(quitchars,ch)) {
if (flags.verbose) pline(Never_mind);
return;
}

File diff suppressed because it is too large Load Diff

View File

@@ -185,6 +185,11 @@ STATIC_DCL char *FDECL(make_lockname, (const char *,char *));
STATIC_DCL FILE *FDECL(fopen_config_file, (const char *));
STATIC_DCL int FDECL(get_uchars, (FILE *,char *,char *,uchar *,BOOLEAN_P,int,const char *));
int FDECL(parse_config_line, (FILE *,char *,char *,char *));
#ifdef ASCIIGRAPH
STATIC_DCL FILE *NDECL(fopen_sym_file);
STATIC_DCL void FDECL(free_symhandling, (BOOLEAN_P));
STATIC_DCL void FDECL(set_symhandling, (char *,BOOLEAN_P));
#endif
#ifdef NOCWD_ASSUMPTIONS
STATIC_DCL void FDECL(adjust_prefix, (char *, int));
#endif
@@ -2047,35 +2052,46 @@ char *tmp_levels;
} else if (match_varname(buf, "BOULDER", 3)) {
(void) get_uchars(fp, buf, bufp, &iflags.bouldersym, TRUE,
1, "BOULDER");
} else if (match_varname(buf, "GRAPHICS", 4)) {
len = get_uchars(fp, buf, bufp, translate, FALSE,
MAXPCHARS, "GRAPHICS");
assign_graphics(translate, len, MAXPCHARS, 0);
} else if (match_varname(buf, "DUNGEON", 4)) {
len = get_uchars(fp, buf, bufp, translate, FALSE,
MAXDCHARS, "DUNGEON");
assign_graphics(translate, len, MAXDCHARS, 0);
} else if (match_varname(buf, "TRAPS", 4)) {
len = get_uchars(fp, buf, bufp, translate, FALSE,
MAXTCHARS, "TRAPS");
assign_graphics(translate, len, MAXTCHARS, MAXDCHARS);
} else if (match_varname(buf, "EFFECTS", 4)) {
len = get_uchars(fp, buf, bufp, translate, FALSE,
MAXECHARS, "EFFECTS");
assign_graphics(translate, len, MAXECHARS, MAXDCHARS+MAXTCHARS);
} else if (match_varname(buf, "OBJECTS", 3)) {
/* oc_syms[0] is the RANDOM object, unused */
(void) get_uchars(fp, buf, bufp, &(oc_syms[1]), TRUE,
MAXOCLASSES-1, "OBJECTS");
} else if (match_varname(buf, "MONSTERS", 3)) {
/* monsyms[0] is unused */
(void) get_uchars(fp, buf, bufp, &(monsyms[1]), TRUE,
MAXMCLASSES-1, "MONSTERS");
} else if (match_varname(buf, "WARNINGS", 5)) {
(void) get_uchars(fp, buf, bufp, translate, FALSE,
WARNCOUNT, "WARNINGS");
assign_warnings(translate);
} else if (match_varname(buf, "SYMBOLS", 4)) {
#ifdef ASCIIGRAPH
char *op, symbuf[BUFSZ];
boolean morelines;
do {
morelines = FALSE;
/* strip leading and trailing white space */
while (isspace(*bufp)) bufp++;
op = eos(bufp);
while (--op >= bufp && isspace(*op)) *op = '\0';
/* check for line continuation (trailing '\') */
op = eos(bufp);
if (--op >= bufp && *op == '\\') {
*op = '\0';
morelines = TRUE;
/* strip trailing space now that '\' is gone */
while (--op >= bufp && isspace(*op)) *op = '\0';
}
/* parse here */
parsesymbols(bufp);
if (morelines)
do {
*symbuf = '\0';
if (!fgets(symbuf, BUFSZ, fp)) {
morelines = FALSE;
break;
}
bufp = symbuf;
} while (*bufp == '#');
} while (morelines);
switch_graphics(TRUE);
#endif /*ASCIIGRAPH*/
#ifdef WIZARD
} else if (match_varname(buf, "WIZKIT", 6)) {
(void) strncpy(wizkit, bufp, WIZKIT_MAX-1);
@@ -2405,6 +2421,218 @@ read_wizkit()
#endif /*WIZARD*/
#ifdef ASCIIGRAPH
extern struct symparse loadsyms[]; /* drawing.c */
extern struct textlist *symset_list; /* options.c */
static int symset_count = 0; /* for pick-list building only */
static boolean chosen_symset_start = FALSE, chosen_symset_end = FALSE;
STATIC_OVL
FILE *
fopen_sym_file()
{
FILE *fp;
fp = fopen_datafile(SYMBOLS, "r", HACKPREFIX);
return fp;
}
/*
* Returns 1 if the chose symset was found and loaded.
* 0 if it wasn't found in the sym file or other problem.
*/
int
read_sym_file(rogueflag)
boolean rogueflag;
{
char buf[4*BUFSZ];
FILE *fp;
if (!(fp = fopen_sym_file())) return 0;
symset_count = 0;
chosen_symset_start = chosen_symset_end = FALSE;
while (fgets(buf, 4*BUFSZ, fp)) {
if (!parse_sym_line(buf, rogueflag)) {
raw_printf("Bad symbol line: \"%.50s\"", buf);
wait_synch();
}
}
(void) fclose(fp);
if (!chosen_symset_end && !chosen_symset_start) return 0;
if (!chosen_symset_end) {
raw_printf("Missing finish for symset \"%s\"",
#ifdef REINCARNATION
rogueflag ? roguesymset :
#endif
symset);
wait_synch();
}
return 1;
}
/* returns 0 on error */
int
parse_sym_line(buf, rogueflag)
char *buf;
boolean rogueflag;
{
int val;
struct symparse *symp = (struct symparse *)0;
char *bufp, *commentp, *altp;
char *symsetname =
#ifdef REINCARNATION
rogueflag ? roguesymset :
#endif
symset;
if (*buf == '#')
return 1;
/* remove trailing comment(s) */
commentp = eos(buf);
while (--commentp > buf) {
if (*commentp != '#') continue;
*commentp = '\0';
}
/* remove trailing whitespace */
bufp = eos(buf);
while (--bufp > buf && isspace(*bufp))
continue;
if (bufp <= buf)
return 1; /* skip all-blank lines */
else
*(bufp + 1) = '\0'; /* terminate line */
/* skip leading whitespace on option name */
while (isspace(*buf)) ++buf;
/* 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 */
chosen_symset_start = FALSE;
chosen_symset_end = TRUE;
return 1;
}
return 0;
}
/* skip whitespace between '=' and value */
do { ++bufp; } while (isspace(*bufp));
symp = match_sym(buf);
if (!symp)
return 0;
if (!symsetname) {
/* A null symsetname 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 && symp->idx == 0) {
struct textlist *tmpsp;
tmpsp = (struct textlist *)alloc(sizeof(struct textlist));
tmpsp->next = (struct textlist *)0;
if (!symset_list) {
symset_list = tmpsp;
symset_count = 0;
} else {
symset_count++;
tmpsp->next = symset_list;
symset_list = tmpsp;
}
tmpsp->idx = symset_count;
tmpsp->text = (char *)alloc(strlen(bufp)+1);
Strcpy(tmpsp->text, bufp);
}
return 1;
}
if (symp->range) {
if (symp->range == SYM_CONTROL) {
switch(symp->idx) {
case 0:
/* start of symset */
if (!strcmpi(bufp, symsetname)) { /* desired one? */
chosen_symset_start = TRUE;
#ifdef REINCARNATION
if (rogueflag)
init_r_symbols();
else
#endif
init_l_symbols();
free_symhandling(rogueflag);
}
break;
case 1:
/* finish symset */
chosen_symset_start = FALSE;
chosen_symset_end = TRUE;
break;
case 2:
/* handler type identified */
if (chosen_symset_start)
set_symhandling(bufp, rogueflag);
break;
}
} else { /* !SYM_CONTROL */
val = sym_val(bufp);
if (chosen_symset_start) {
#ifdef REINCARNATION
if (rogueflag)
update_r_symset(symp, val);
else
#endif
update_l_symset(symp, val);
}
}
}
return 1;
}
STATIC_OVL void
free_symhandling(rogueflag)
boolean rogueflag;
{
if (rogueflag) {
#ifdef REINCARNATION
if (roguehandling) {
free((genericptr_t)roguehandling);
roguehandling = (char *)0;
}
#endif
} else {
if (symhandling) {
free((genericptr_t)symhandling);
symhandling = (char *)0;
}
}
}
STATIC_OVL void
set_symhandling(handling, rogueflag)
char *handling;
boolean rogueflag;
{
char *new_handling;
free_symhandling(rogueflag);
if (!handling) return;
new_handling = (char *)alloc(strlen(handling)+1);
Strcpy(new_handling, handling);
#ifdef REINCARNATION
if (rogueflag)
roguehandling = new_handling;
#endif
if (!rogueflag)
symhandling = new_handling;
}
#endif /*ASCIIGRAPH*/
/* ---------- END CONFIG FILE HANDLING ----------- */
/* ---------- BEGIN SCOREBOARD CREATION ----------- */

View File

@@ -806,7 +806,7 @@ register const char *let,*word;
if(allownone) *bp++ = '-';
#ifndef GOLDOBJ
if(allowgold) *bp++ = def_oc_syms[COIN_CLASS];
if(allowgold) *bp++ = def_oc_syms[COIN_CLASS].sym;
#endif
if(bp > buf && bp[-1] == '-') *bp++ = ' ';
ap = altlets;
@@ -981,7 +981,7 @@ register const char *let,*word;
if(ilet == '-') {
return(allownone ? &zeroobj : (struct obj *) 0);
}
if(ilet == def_oc_syms[COIN_CLASS]) {
if(ilet == def_oc_syms[COIN_CLASS].sym) {
if (!usegold) {
You("cannot %s gold.", word);
return(struct obj *)0;
@@ -1035,7 +1035,7 @@ register const char *let,*word;
* counts for other things since the throw code will
* split off a single item anyway */
#ifdef GOLDOBJ
if (ilet != def_oc_syms[COIN_CLASS])
if (ilet != def_oc_syms[COIN_CLASS].sym)
#endif
allowcnt = 1;
if(cnt == 0 && prezero) return((struct obj *)0);
@@ -2101,8 +2101,8 @@ dotypeinv()
if (!billx) *extra_types++ = 'x';
*extra_types = '\0'; /* for index() */
for (i = 0; i < MAXOCLASSES; i++)
if (!index(types, def_oc_syms[i])) {
*extra_types++ = def_oc_syms[i];
if (!index(types, def_oc_syms[i].sym)) {
*extra_types++ = def_oc_syms[i].sym;
*extra_types = '\0';
}

View File

@@ -1295,7 +1295,7 @@ rndmonst()
if (tooweak(mndx, minmlev) || toostrong(mndx, maxmlev))
continue;
#ifdef REINCARNATION
if (upper && !isupper(def_monsyms[(int)(ptr->mlet)])) continue;
if (upper && !isupper(def_monsyms[(int)(ptr->mlet)].sym)) continue;
#endif
if (elemlevel && wrong_elem_type(ptr)) continue;
if (uncommon(mndx)) continue;

View File

@@ -50,10 +50,9 @@ int explcolors[] = {
#ifdef ROGUE_COLOR
# if defined(USE_TILES) && defined(MSDOS)
#define HAS_ROGUE_IBM_GRAPHICS (iflags.IBMgraphics && !iflags.grmode && \
Is_rogue_level(&u.uz))
#define HAS_ROGUE_IBM_GRAPHICS (ROGUEHANDLING("IBM") && !iflags.grmode)
# else
#define HAS_ROGUE_IBM_GRAPHICS (iflags.IBMgraphics && Is_rogue_level(&u.uz))
#define HAS_ROGUE_IBM_GRAPHICS (ROGUEHANDLING("IBM"))
# endif
#endif
@@ -221,11 +220,7 @@ unsigned *ospecial;
#ifdef TEXTCOLOR
/* Turn off color if no color defined, or rogue level w/o PC graphics. */
# ifdef REINCARNATION
# ifdef ASCIIGRAPH
if (!has_color(color) || (Is_rogue_level(&u.uz) && !has_rogue_ibm_graphics))
# else
if (!has_color(color) || Is_rogue_level(&u.uz))
# endif
# else
if (!has_color(color))
# endif

View File

@@ -114,7 +114,7 @@ mkshop()
return;
}
for(i=0; shtypes[i].name; i++)
if(*ep == def_oc_syms[(int)shtypes[i].symb])
if(*ep == def_oc_syms[(int)shtypes[i].symb].sym)
goto gottype;
if(*ep == 'g' || *ep == 'G')
i = 0;

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)options.c 3.5 2006/07/08 */
/* SCCS Id: @(#)options.c 3.5 2006/09/17 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -18,6 +18,7 @@ NEARDATA struct instance_flags iflags; /* provide linkage */
#include <ctype.h>
#endif
#define BACKWARD_COMPAT
#define WINTYPELEN 16
#ifdef DEFAULT_WC_TILED_MAP
@@ -86,11 +87,6 @@ static struct Bool_Opt
{"color", &iflags.wc_color, FALSE, SET_IN_GAME}, /*WC*/
# endif
{"confirm",&flags.confirm, TRUE, SET_IN_GAME},
#if defined(TERMLIB) && !defined(MAC_GRAPHICS_ENV)
{"DECgraphics", &iflags.DECgraphics, FALSE, SET_IN_GAME},
#else
{"DECgraphics", (boolean *)0, FALSE, SET_IN_FILE},
#endif
{"eight_bit_tty", &iflags.wc_eight_bit_input, FALSE, SET_IN_GAME}, /*WC*/
#ifdef TTY_GRAPHICS
{"extmenu", &iflags.extmenu, FALSE, SET_IN_GAME},
@@ -112,11 +108,6 @@ static struct Bool_Opt
{"fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE},
{"help", &flags.help, TRUE, SET_IN_GAME},
{"hilite_pet", &iflags.wc_hilite_pet, FALSE, SET_IN_GAME}, /*WC*/
#ifdef ASCIIGRAPH
{"IBMgraphics", &iflags.IBMgraphics, FALSE, SET_IN_GAME},
#else
{"IBMgraphics", (boolean *)0, FALSE, SET_IN_FILE},
#endif
#ifndef MAC
{"ignintr", &flags.ignintr, FALSE, SET_IN_GAME},
#else
@@ -126,11 +117,6 @@ static struct Bool_Opt
{"legacy", &flags.legacy, TRUE, DISP_IN_GAME},
{"lit_corridor", &flags.lit_corridor, FALSE, SET_IN_GAME},
{"lootabc", &flags.lootabc, FALSE, SET_IN_GAME},
#ifdef MAC_GRAPHICS_ENV
{"Macgraphics", &iflags.MACgraphics, TRUE, SET_IN_GAME},
#else
{"Macgraphics", (boolean *)0, FALSE, SET_IN_FILE},
#endif
#ifdef MAIL
{"mail", &flags.biff, TRUE, SET_IN_GAME},
#else
@@ -245,8 +231,10 @@ static struct Comp_Opt
{ "align_message", "message window alignment", 20, DISP_IN_GAME }, /*WC*/
{ "align_status", "status window alignment", 20, DISP_IN_GAME }, /*WC*/
{ "altkeyhandler", "alternate key handler", 20, DISP_IN_GAME },
{ "boulder", "the symbol to use for displaying boulders",
1, SET_IN_GAME },
#ifdef BACKWARD_COMPAT
{ "boulder", "deprecated (use S_boulder in sym file instead)",
1, SET_IN_FILE },
#endif
{ "catname", "the name of your (first) cat (e.g., catname:Tabby)",
PL_PSIZ, DISP_IN_GAME },
{ "disclose", "the kinds of information to disclose at end of game",
@@ -344,6 +332,13 @@ static struct Comp_Opt
{ "scroll_margin", "scroll map when this far from the edge", 20, DISP_IN_GAME }, /*WC*/
#ifdef MSDOS
{ "soundcard", "type of sound card to use", 20, SET_IN_FILE },
#endif
{ "symset", "load a set of display symbols from the symbols file", 70, SET_IN_GAME },
{ "roguesymset", "load a set of rogue display symbols from the roguesym file", 70,
#ifdef REINCARNATION
SET_IN_GAME },
#else
SET_IN_FILE },
#endif
{ "suppress_alert", "suppress alerts about version-specific features",
8, SET_IN_GAME },
@@ -368,6 +363,13 @@ static struct Comp_Opt
{ "windowcolors", "the foreground/background colors of windows", /*WC*/
80, DISP_IN_GAME },
{ "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME },
#ifdef BACKWARD_COMPAT
{"DECgraphics", "deprecated", 70, SET_IN_FILE},
{"IBMgraphics", "deprecated", 70, SET_IN_FILE},
# ifdef MAC_GRAPHICS_ENV
{"Macgraphics", "deprecated", 70, SET_IN_FILE},
# endif
#endif
{ (char *)0, (char *)0, 0, 0 }
};
@@ -580,15 +582,12 @@ initoptions()
flags.initgend = -1;
flags.initalign = -1;
/* Set the default monster and object class symbols. Don't use */
/* memcpy() --- sizeof char != sizeof uchar on some machines. */
for (i = 0; i < MAXOCLASSES; i++)
oc_syms[i] = (uchar) def_oc_syms[i];
for (i = 0; i < MAXMCLASSES; i++)
monsyms[i] = (uchar) def_monsyms[i];
/* Set the default monster and object class symbols. */
init_symbols();
for (i = 0; i < WARNCOUNT; i++)
warnsyms[i] = def_warnsyms[i].sym;
iflags.bouldersym = 0;
iflags.travelcc.x = iflags.travelcc.y = -1;
/* assert( sizeof flags.inv_order == sizeof def_inv_order ); */
@@ -599,7 +598,7 @@ initoptions()
for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++)
flags.end_disclose[i] = DISCLOSE_PROMPT_DEFAULT_NO;
switch_graphics(ASCII_GRAPHICS); /* set default characters */
switch_graphics(DEFAULT_GRAPHICS); /* set default characters */
#if defined(UNIX) && defined(TTY_GRAPHICS)
/*
* Set defaults for some options depending on what we can
@@ -610,7 +609,13 @@ initoptions()
*/
/* this detects the IBM-compatible console on most 386 boxes */
if ((opts = nh_getenv("TERM")) && !strncmp(opts, "AT", 2)) {
switch_graphics(IBM_GRAPHICS);
#ifdef ASCIIGRAPH
if (!symset) load_symset("IBMGraphics", FALSE);
if (!roguesymset) load_symset("IBMGraphics", TRUE);
switch_graphics(TRUE);
#endif
# ifdef TEXTCOLOR
iflags.use_color = TRUE;
# endif
@@ -622,13 +627,20 @@ initoptions()
if ((opts = nh_getenv("TERM")) &&
!strncmpi(opts, "vt", 2) && AS && AE &&
index(AS, '\016') && index(AE, '\017')) {
switch_graphics(DEC_GRAPHICS);
# ifdef ASCIIGRAPH
if (!symset) load_symset("DECGraphics", FALSE);
switch_graphics(TRUE);
# endif /*ASCIIGRAPH*/
}
# endif
#endif /* UNIX || VMS */
#ifdef MAC_GRAPHICS_ENV
switch_graphics(MAC_GRAPHICS);
if (!symset) load_symset("MACGraphics", FALSE);
switch_graphics(TRUE);
#endif /* MAC_GRAPHICS_ENV */
flags.menu_style = MENU_FULL;
@@ -866,27 +878,6 @@ char *op;
return 1;
}
STATIC_OVL void
graphics_opts(opts, optype, maxlen, offset)
register char *opts;
const char *optype;
int maxlen, offset;
{
uchar translate[MAXPCHARS+1];
int length, i;
if (!(opts = string_for_env_opt(optype, opts, FALSE)))
return;
escapes(opts, opts);
length = strlen(opts);
if (length > maxlen) length = maxlen;
/* match the form obtained from PC configuration files */
for (i = 0; i < length; i++)
translate[i] = (uchar) opts[i];
assign_graphics(translate, length, maxlen, offset);
}
STATIC_OVL void
warning_opts(opts, optype)
register char *opts;
@@ -1305,6 +1296,49 @@ boolean tinitial, tfrom_file;
return;
}
fullname = "roguesymset";
if (match_optname(opts, fullname, 7, TRUE)) {
#if defined(REINCARNATION) && defined(ASCIIGRAPH)
if (duplicate) complain_about_duplicate(opts,1);
if (negated) bad_negation(fullname, FALSE);
else if ((op = string_for_opt(opts, FALSE)) != 0) {
roguesymset = (char *)alloc(strlen(op) + 1);
Strcpy(roguesymset, op);
if (!read_sym_file(TRUE)) {
badoption(opts);
free((char *)roguesymset);
roguesymset = (char *)0;
} else {
if (!initial && Is_rogue_level(&u.uz))
assign_rogue_graphics(TRUE);
need_redraw = TRUE;
}
}
#endif
return;
}
fullname = "symset";
if (match_optname(opts, fullname, 6, TRUE)) {
#ifdef ASCIIGRAPH
if (duplicate) complain_about_duplicate(opts,1);
if (negated) bad_negation(fullname, FALSE);
else if ((op = string_for_opt(opts, FALSE)) != 0) {
symset = (char *)alloc(strlen(op) + 1);
Strcpy(symset, op);
if (!read_sym_file(FALSE)) {
badoption(opts);
free((char *)symset);
symset = (char *)0;
} else {
switch_graphics(TRUE);
need_redraw = TRUE;
}
}
#endif
return;
}
fullname = "runmode";
if (match_optname(opts, fullname, 4, TRUE)) {
if (duplicate) complain_about_duplicate(opts,1);
@@ -1566,93 +1600,6 @@ goodfruit:
*/
return;
}
/* graphics:string */
fullname = "graphics";
if (match_optname(opts, fullname, 2, TRUE)) {
if (duplicate) complain_about_duplicate(opts,1);
if (negated) bad_negation(fullname, FALSE);
else graphics_opts(opts, fullname, MAXPCHARS, 0);
return;
}
fullname = "dungeon";
if (match_optname(opts, fullname, 2, TRUE)) {
if (duplicate) complain_about_duplicate(opts,1);
if (negated) bad_negation(fullname, FALSE);
else graphics_opts(opts, fullname, MAXDCHARS, 0);
return;
}
fullname = "traps";
if (match_optname(opts, fullname, 2, TRUE)) {
if (duplicate) complain_about_duplicate(opts,1);
if (negated) bad_negation(fullname, FALSE);
else graphics_opts(opts, fullname, MAXTCHARS, MAXDCHARS);
return;
}
fullname = "effects";
if (match_optname(opts, fullname, 2, TRUE)) {
if (duplicate) complain_about_duplicate(opts,1);
if (negated) bad_negation(fullname, FALSE);
else
graphics_opts(opts, fullname, MAXECHARS, MAXDCHARS+MAXTCHARS);
return;
}
/* objects:string */
fullname = "objects";
if (match_optname(opts, fullname, 7, TRUE)) {
int length;
if (duplicate) complain_about_duplicate(opts,1);
if (negated) {
bad_negation(fullname, FALSE);
return;
}
if (!(opts = string_for_env_opt(fullname, opts, FALSE)))
return;
escapes(opts, opts);
/*
* Override the default object class symbols. The first
* object in the object class is the "random object". I
* don't want to use 0 as an object class, so the "random
* object" is basically a place holder.
*
* The object class symbols have already been initialized in
* initoptions().
*/
length = strlen(opts);
if (length >= MAXOCLASSES)
length = MAXOCLASSES-1; /* don't count RANDOM_OBJECT */
for (i = 0; i < length; i++)
oc_syms[i+1] = (uchar) opts[i];
return;
}
/* monsters:string */
fullname = "monsters";
if (match_optname(opts, fullname, 8, TRUE)) {
int length;
if (duplicate) complain_about_duplicate(opts,1);
if (negated) {
bad_negation(fullname, FALSE);
return;
}
if (!(opts = string_for_env_opt(fullname, opts, FALSE)))
return;
escapes(opts, opts);
/* Override default mon class symbols set in initoptions(). */
length = strlen(opts);
if (length >= MAXMCLASSES)
length = MAXMCLASSES-1; /* mon class 0 unused */
for (i = 0; i < length; i++)
monsyms[i+1] = (uchar) opts[i];
return;
}
fullname = "warnings";
if (match_optname(opts, fullname, 5, TRUE)) {
if (duplicate) complain_about_duplicate(opts,1);
@@ -1660,6 +1607,7 @@ goodfruit:
else warning_opts(opts, fullname);
return;
}
#ifdef BACKWARD_COMPAT
/* boulder:symbol */
fullname = "boulder";
if (match_optname(opts, fullname, 7, TRUE)) {
@@ -1692,6 +1640,7 @@ goodfruit:
if (!initial) need_redraw = TRUE;
return;
}
#endif
/* name:string */
fullname = "name";
@@ -2301,7 +2250,7 @@ goodfruit:
isbad = TRUE;
else /* reject default object class symbols */
for (j = 1; j < MAXOCLASSES; j++)
if (c == def_oc_syms[i]) {
if (c == def_oc_syms[i].sym) {
isbad = TRUE;
break;
}
@@ -2331,20 +2280,102 @@ goodfruit:
badoption(opts);
return;
}
#endif
#ifdef ASCIIGRAPH
# if defined(BACKWARD_COMPAT)
fullname = "DECgraphics";
if (match_optname(opts, fullname, 10, TRUE)) {
boolean badflag = FALSE;
if (duplicate) complain_about_duplicate(opts,1);
if (!negated) {
if (symset) badflag = TRUE;
else {
symset = (char *)alloc(strlen(fullname) + 1);
Strcpy(symset, fullname);
if (!read_sym_file(FALSE)) {
badflag = TRUE;
free((char *)symset);
symset = (char *)0;
} else switch_graphics(TRUE);
}
if (badflag) {
pline("Failure to load symbol set %s.",
fullname);
wait_synch();
}
}
return;
}
fullname = "IBMgraphics";
if (match_optname(opts, fullname, 10, TRUE)) {
boolean badflag = FALSE;
if (duplicate) complain_about_duplicate(opts,1);
if (!negated) {
if (symset) badflag = TRUE;
else {
symset = (char *)alloc(strlen(fullname) + 1);
Strcpy(symset, fullname);
if (!read_sym_file(FALSE)) {
badflag = TRUE;
free((char *)symset);
symset = (char *)0;
} else switch_graphics(TRUE);
}
#ifdef REINCARNATION
if (roguesymset) badflag = TRUE;
else {
roguesymset = (char *)alloc(strlen(fullname) + 1);
Strcpy(roguesymset, fullname);
if (!read_sym_file(TRUE)) {
badflag = TRUE;
free((char *)roguesymset);
roguesymset = (char *)0;
}
if (!initial && Is_rogue_level(&u.uz))
assign_rogue_graphics(TRUE);
}
#endif
if (badflag) {
pline("Failure to load symbol set %s.",
fullname);
wait_synch();
}
}
return;
}
# ifdef MAC_GRAPHICS_ENV
fullname = "MACgraphics";
if (match_optname(opts, fullname, 11, TRUE)) {
boolean badflag = FALSE;
if (duplicate) complain_about_duplicate(opts,1);
if (!negated) {
if (symset) badflag = TRUE;
else {
symset = (char *)alloc(strlen(fullname) + 1);
Strcpy(symset, fullname);
if (!read_sym_file(FALSE)) {
badflag = TRUE;
free((char *)symset);
symset = (char *)0;
} else switch_graphics(TRUE);
}
if (badflag) {
pline("Failure to load symbol set %s.",
fullname);
wait_synch();
}
}
return;
}
# endif
# endif
#endif
/* OK, if we still haven't recognized the option, check the boolean
* options list
*/
for (i = 0; boolopt[i].name; i++) {
if (match_optname(opts, boolopt[i].name, 3, FALSE)) {
#if defined(TERMLIB) || defined(ASCIIGRAPH) || defined(MAC_GRAPHICS_ENV)
/* need to remember previous XXXgraphics setting
in order to prevent explicit "noXXXgraphics" from
overriding a preceding "YYYgraphics" request;
noXXXgraphics will reset to ordinary ASCII only
if/when XXXgraphics is currently in effect */
boolean old_gfx = boolopt[i].addr && *boolopt[i].addr;
#endif
/* options that don't exist */
if (!boolopt[i].addr) {
@@ -2365,50 +2396,6 @@ goodfruit:
if (duplicate_opt_detection(boolopt[i].name, 0))
complain_about_duplicate(boolopt[i].name,0);
#if defined(TERMLIB) || defined(ASCIIGRAPH) || defined(MAC_GRAPHICS_ENV)
if (FALSE
# ifdef TERMLIB
|| (boolopt[i].addr) == &iflags.DECgraphics
# endif
# ifdef ASCIIGRAPH
|| (boolopt[i].addr) == &iflags.IBMgraphics
# endif
# ifdef MAC_GRAPHICS_ENV
|| (boolopt[i].addr) == &iflags.MACgraphics
# endif
) {
# ifdef REINCARNATION
if (!initial && Is_rogue_level(&u.uz))
assign_rogue_graphics(FALSE);
# endif
need_redraw = TRUE;
# ifdef TERMLIB
if ((boolopt[i].addr) == &iflags.DECgraphics) {
if (iflags.DECgraphics != old_gfx)
switch_graphics(iflags.DECgraphics ?
DEC_GRAPHICS : ASCII_GRAPHICS);
}
# endif
# ifdef ASCIIGRAPH
if ((boolopt[i].addr) == &iflags.IBMgraphics) {
if (iflags.IBMgraphics != old_gfx)
switch_graphics(!negated ?
IBM_GRAPHICS : ASCII_GRAPHICS);
}
# endif
# ifdef MAC_GRAPHICS_ENV
if ((boolopt[i].addr) == &iflags.MACgraphics) {
if (iflags.MACgraphics != old_gfx)
switch_graphics(iflags.MACgraphics ?
MAC_GRAPHICS : ASCII_GRAPHICS);
}
# endif
# ifdef REINCARNATION
if (!initial && Is_rogue_level(&u.uz))
assign_rogue_graphics(TRUE);
# endif
}
#endif /* TERMLIB || ASCIIGRAPH || MAC_GRAPHICS_ENV */
#ifdef RLECOMP
if ((boolopt[i].addr) == &iflags.rlecomp) {
if (*boolopt[i].addr)
@@ -2517,7 +2504,7 @@ oc_to_str(src,dest)
if (i < 0 || i >= MAXOCLASSES)
impossible("oc_to_str: illegal object class %d", i);
else
*dest++ = def_oc_syms[i];
*dest++ = def_oc_syms[i].sym;
}
*dest = '\0';
}
@@ -2791,6 +2778,8 @@ doset()
return 0;
}
struct textlist *symset_list; /* files.c will populate this wil list of available sets */
STATIC_OVL boolean
special_handling(optname, setinitial, setfromfile)
const char *optname;
@@ -3148,6 +3137,102 @@ boolean setinitial,setfromfile;
if (pick_cnt >= 0) goto ape_again;
}
#endif /* AUTOPICKUP_EXCEPTIONS */
#ifdef ASCIIGRAPH
} else if (!strcmp("symset", optname) ||
!strcmp("roguesymset", optname)) {
menu_item *symset_pick = (menu_item *)0;
boolean rogueflag = (*optname == 'r');
char *symset_name;
int chosen = -2;
/* clear symset/roguesymset as a flag to read_sym_file() to build list */
if (!rogueflag) {
symset_name = symset;
symset = (char *)0;
}
#ifdef REINCARNATION
if (rogueflag) {
symset_name = roguesymset;
roguesymset = (char *)0;
}
#endif
if (read_sym_file(rogueflag) && symset_list) {
int let = 'a';
struct textlist *sl;
tmpwin = create_nhwindow(NHW_MENU);
start_menu(tmpwin);
any.a_int = 1;
add_menu(tmpwin, NO_GLYPH, &any, let++, 0,
ATR_NONE, "NetHack default", MENU_UNSELECTED);
sl = symset_list;
while (sl) {
if (sl->text) {
any.a_int = sl->idx + 2;
add_menu(tmpwin, NO_GLYPH, &any, let, 0,
ATR_NONE, sl->text, MENU_UNSELECTED);
sl = sl->next;
if (let == 'z') let = 'A';
else let++;
}
}
end_menu(tmpwin, "Select symbol set:");
if (select_menu(tmpwin, PICK_ONE, &symset_pick) > 0) {
chosen = symset_pick->item.a_int - 2;
free((genericptr_t)symset_pick);
}
destroy_nhwindow(tmpwin);
if (chosen > -1) {
sl = symset_list;
while (sl) {
if (sl->idx == chosen) {
if (symset_name)
free((genericptr_t)symset_name);
symset_name = (char *)alloc(strlen(sl->text)+1);
Strcpy(symset_name, sl->text);
}
sl = sl->next;
}
}
/* clean up */
while (symset_list) {
sl = symset_list;
if (sl->text) free((genericptr_t)sl->text);
symset_list = sl->next;
free((genericptr_t)sl);
}
symset_list = (struct textlist *)0;
}
if(!rogueflag) {
init_l_symbols();
if (chosen >= 0) {
symset = symset_name;
if (!read_sym_file(FALSE)) {
free((genericptr_t)symset);
symset = (char *)0;
}
}
}
# ifdef REINCARNATION
if (rogueflag) {
init_r_symbols();
if (chosen >= 0) {
roguesymset = symset_name;
if (!read_sym_file(TRUE)) {
free((genericptr_t)roguesymset);
roguesymset = (char *)0;
}
}
}
if (Is_rogue_level(&u.uz))
assign_rogue_graphics(TRUE);
else
assign_rogue_graphics(FALSE);
#else
switch_graphics(TRUE);
# endif
need_redraw = TRUE;
#endif /*ASCIIGRAPH*/
} else {
/* didn't match any of the special options */
return FALSE;
@@ -3192,9 +3277,11 @@ char *buf;
Sprintf(buf, "%s", iflags.altkeyhandler[0] ?
iflags.altkeyhandler : "default");
#endif
#ifdef BACKWARD_COMPAT
else if (!strcmp(optname, "boulder"))
Sprintf(buf, "%c", iflags.bouldersym ?
iflags.bouldersym : oc_syms[(int)objects[BOULDER].oc_class]);
#endif
else if (!strcmp(optname, "catname"))
Sprintf(buf, "%s", catname[0] ? catname : none );
else if (!strcmp(optname, "disclose")) {
@@ -3343,6 +3430,10 @@ char *buf;
}
else if (!strcmp(optname, "race"))
Sprintf(buf, "%s", rolestring(flags.initrace, races, noun));
#ifdef REINCARNATION
else if (!strcmp(optname, "roguesymset"))
Sprintf(buf, "%s", roguesymset ? roguesymset : "default");
#endif
else if (!strcmp(optname, "role"))
Sprintf(buf, "%s", rolestring(flags.initrole, roles, name.m));
else if (!strcmp(optname, "runmode"))
@@ -3374,6 +3465,8 @@ char *buf;
FEATURE_NOTICE_VER_MIN,
FEATURE_NOTICE_VER_PATCH);
}
else if (!strcmp(optname, "symset"))
Sprintf(buf, "%s", symset ? symset : "default");
else if (!strcmp(optname, "tile_file"))
Sprintf(buf, "%s", iflags.wc_tile_file ? iflags.wc_tile_file : defopt);
else if (!strcmp(optname, "tile_height")) {
@@ -3548,6 +3641,110 @@ free_autopickup_exceptions()
}
}
#endif /* AUTOPICKUP_EXCEPTIONS */
#ifdef ASCIIGRAPH
/* bundle some common usage into one easy-to-use routine */
int
load_symset(s, rogueflag)
const char *s;
boolean rogueflag;
{
#ifdef REINCARNATION
if (rogueflag) {
if (roguesymset) free((genericptr_t)roguesymset);
roguesymset = (char *)alloc(strlen(s)+1);
Strcpy(roguesymset,s);
if (read_sym_file(TRUE))
switch_graphics(TRUE);
else {
free((genericptr_t)roguesymset);
roguesymset = (char *)0;
return 0;
}
}
#endif
if (!rogueflag) {
if (symset) free((genericptr_t)symset);
symset = (char *)alloc(strlen(s)+1);
Strcpy(symset,s);
if (read_sym_file(FALSE))
switch_graphics(TRUE);
else {
free((genericptr_t)symset);
symset = (char *)0;
return 0;
}
}
return 1;
}
/* Parse the value of a SYMBOLS line from a config file */
void
parsesymbols(opts)
register char *opts;
{
int val;
char *op, *symname, *strval, *p;
struct symparse *symp;
if ((op = index(opts, ',')) != 0) {
*op++ = 0;
parsesymbols(op);
}
/* S_sample:string */
symname = opts;
strval = index(opts, ':');
if (!symname || !strval) return;
*strval++ = 0;
/* strip leading and trailing white space from symname */
while (isspace(*symname)) symname++;
p = eos(symname);
while (--p >= symname && isspace(*p)) *p = '\0';
/* strip leading and trailing white space from strval */
while (isspace(*strval)) strval++;
p = eos(strval);
while (--p >= strval && isspace(*p)) *p = '\0';
symp = match_sym(symname);
if (!symp) return;
if (symp->range && symp->range != SYM_CONTROL) {
val = sym_val(strval);
update_l_symset(symp, val);
}
}
struct symparse *
match_sym(buf)
char *buf;
{
size_t len = strlen(buf);
const char *p = index(buf, ':'),
*q = index(buf, '=');
struct symparse *sp = loadsyms;
if (!p || (q && q < p)) p = q;
while(p && p > buf && isspace(*(p-1))) p--;
if (p) len = (int)(p - buf);
while(sp->range) {
if ((len >= strlen(sp->name)) && !strncmpi(buf, sp->name, len))
return sp;
sp++;
}
return (struct symparse *)0;
}
int sym_val(strval)
char *strval;
{
char buf[QBUFSZ];
buf[0] = '\0';
escapes(strval, buf);
return (int)*buf;
}
#endif
/* data for option_help() */
static const char *opt_intro[] = {
@@ -3792,12 +3989,12 @@ char *class_select;
selected = FALSE;
switch (category) {
case 0:
text = monexplain[def_char_to_monclass(*class_list)];
text = def_monsyms[def_char_to_monclass(*class_list)].explain;
accelerator = *class_list;
Sprintf(buf, "%s", text);
break;
case 1:
text = objexplain[def_char_to_objclass(*class_list)];
text = def_oc_syms[def_char_to_objclass(*class_list)].explain;
accelerator = next_accelerator;
Sprintf(buf, "%c %s", *class_list, text);
break;

View File

@@ -573,15 +573,15 @@ do_look(mode, click_cc)
/* Check for monsters */
for (i = 0; i < MAXMCLASSES; i++) {
if (sym == ((from_screen || clicklook) ? monsyms[i] : def_monsyms[i]) &&
monexplain[i]) {
if (sym == ((from_screen || clicklook) ? monsyms[i] : def_monsyms[i].sym) &&
def_monsyms[i].explain) {
need_to_look = TRUE;
if (!found) {
Sprintf(out_str, "%c %s", sym, an(monexplain[i]));
firstmatch = monexplain[i];
Sprintf(out_str, "%c %s", sym, an(def_monsyms[i].explain));
firstmatch = def_monsyms[i].explain;
found++;
} else {
found += append_str(out_str, an(monexplain[i]));
found += append_str(out_str, an(def_monsyms[i].explain));
}
}
}
@@ -590,7 +590,7 @@ do_look(mode, click_cc)
symbol; firstmatch is assumed to already be set for '@' */
if (((from_screen || clicklook) ?
(sym == monsyms[S_HUMAN] && cc.x == u.ux && cc.y == u.uy) :
(sym == def_monsyms[S_HUMAN] && !flags.showrace)) &&
(sym == def_monsyms[S_HUMAN].sym && !flags.showrace)) &&
!(Race_if(PM_HUMAN) || Race_if(PM_ELF)) && !Upolyd)
found += append_str(out_str, "you"); /* tack on "or you" */
@@ -611,18 +611,18 @@ do_look(mode, click_cc)
/* Now check for objects */
for (i = 1; i < MAXOCLASSES; i++) {
if (sym == ((from_screen || clicklook) ? oc_syms[i] : def_oc_syms[i])) {
if (sym == ((from_screen || clicklook) ? oc_syms[i] : def_oc_syms[i].sym)) {
need_to_look = TRUE;
if ((from_screen || clicklook) && i == VENOM_CLASS) {
skipped_venom++;
continue;
}
if (!found) {
Sprintf(out_str, "%c %s", sym, an(objexplain[i]));
firstmatch = objexplain[i];
Sprintf(out_str, "%c %s", sym, an(def_oc_syms[i].explain));
firstmatch = def_oc_syms[i].explain;
found++;
} else {
found += append_str(out_str, an(objexplain[i]));
found += append_str(out_str, an(def_oc_syms[i].explain));
}
}
}
@@ -697,7 +697,7 @@ do_look(mode, click_cc)
/* if we ignored venom and list turned out to be short, put it back */
if (skipped_venom && found < 2) {
x_str = objexplain[VENOM_CLASS];
x_str = def_oc_syms[VENOM_CLASS].explain;
if (!found) {
Sprintf(out_str, "%c %s", sym, an(x_str));
firstmatch = x_str;

View File

@@ -119,11 +119,11 @@ int *itemcount;
*itemcount = 0;
#ifndef GOLDOBJ
if (incl_gold)
ilets[iletct++] = def_oc_syms[COIN_CLASS];
ilets[iletct++] = def_oc_syms[COIN_CLASS].sym;
#endif
ilets[iletct] = '\0'; /* terminate ilets so that index() will work */
while (otmp) {
c = def_oc_syms[(int)otmp->oclass];
c = def_oc_syms[(int)otmp->oclass].sym;
if (!index(ilets, c) && (!filter || (*filter)(otmp)))
ilets[iletct++] = c, ilets[iletct] = '\0';
*itemcount += 1;
@@ -785,7 +785,7 @@ boolean FDECL((*allow), (OBJ_P));/* allow function */
any.a_obj = curr;
add_menu(win, obj_to_glyph(curr), &any,
qflags & USE_INVLET ? curr->invlet : 0,
def_oc_syms[(int)objects[curr->otyp].oc_class],
def_oc_syms[(int)objects[curr->otyp].oc_class].sym,
ATR_NONE, doname(curr), MENU_UNSELECTED);
}
}
@@ -901,7 +901,7 @@ int how; /* type of query */
any = zeroany;
any.a_int = curr->oclass;
add_menu(win, NO_GLYPH, &any, invlet++,
def_oc_syms[(int)objects[curr->otyp].oc_class],
def_oc_syms[(int)objects[curr->otyp].oc_class].sym,
ATR_NONE, let_to_name(*pack, FALSE),
MENU_UNSELECTED);
collected_type_name = TRUE;

View File

@@ -1612,7 +1612,7 @@ do_class_genocide()
if (strlen(buf) == 1) {
if (buf[0] == ILLOBJ_SYM)
buf[0] = def_monsyms[S_MIMIC];
buf[0] = def_monsyms[S_MIMIC].sym;
class = def_char_to_monclass(buf[0]);
} else {
char buf2[BUFSZ];
@@ -1624,7 +1624,7 @@ do_class_genocide()
immunecnt = gonecnt = goodcnt = 0;
for (i = LOW_PM; i < NUMMONS; i++) {
if (class == 0 &&
strstri(monexplain[(int)mons[i].mlet], buf) != 0)
strstri(def_monsyms[(int)mons[i].mlet].explain, buf) != 0)
class = mons[i].mlet;
if (mons[i].mlet == class) {
if (!(mons[i].geno & G_GENO)) immunecnt++;

View File

@@ -113,7 +113,7 @@ struct obj *obj;
case P_NONE:
/* not a weapon: use item class name; override "food" for corpses */
descr = (obj->otyp == CORPSE) ? "corpse" :
oclass_names[(int)obj->oclass];
def_oc_syms[(int)obj->oclass].name;
break;
case P_SLING:
if (is_ammo(obj))
@@ -121,7 +121,7 @@ struct obj *obj;
/* avoid "rock"; what about known glass? */
(obj->oclass == GEM_CLASS) ? "gem" :
/* in case somebody adds odd sling ammo */
oclass_names[(int)obj->oclass];
def_oc_syms[(int)obj->oclass].name;
break;
case P_BOW:
if (is_ammo(obj)) descr = "arrow";