1/* SCCS Id: @(#)mapglyph.c 3.4 2003/01/08 */ 2/* Copyright (c) David Cohrs, 1991 */ 3/* NetHack may be freely redistributed. See license for details. */ 4 5#include "hack.h" 6#if defined(TTY_GRAPHICS) 7#include "wintty.h" /* for prototype of has_color() only */ 8#endif 9#include "color.h" 10#define HI_DOMESTIC CLR_WHITE /* monst.c */ 11 12int explcolors[] = { 13 CLR_BLACK, /* dark */ 14 CLR_GREEN, /* noxious */ 15 CLR_BROWN, /* muddy */ 16 CLR_BLUE, /* wet */ 17 CLR_MAGENTA, /* magical */ 18 CLR_ORANGE, /* fiery */ 19 CLR_WHITE, /* frosty */ 20}; 21 22#if !defined(TTY_GRAPHICS) 23#define has_color(n) TRUE 24#endif 25 26#ifdef TEXTCOLOR 27#define zap_color(n) color = iflags.use_color ? zapcolors[n] : NO_COLOR 28#define cmap_color(n) color = iflags.use_color ? defsyms[n].color : NO_COLOR 29#define obj_color(n) color = iflags.use_color ? objects[n].oc_color : NO_COLOR 30#define mon_color(n) color = iflags.use_color ? mons[n].mcolor : NO_COLOR 31#define invis_color(n) color = NO_COLOR 32#define pet_color(n) color = iflags.use_color ? mons[n].mcolor : NO_COLOR 33#define warn_color(n) color = iflags.use_color ? def_warnsyms[n].color : NO_COLOR 34#define explode_color(n) color = iflags.use_color ? explcolors[n] : NO_COLOR 35# if defined(REINCARNATION) && defined(ASCIIGRAPH) 36# define ROGUE_COLOR 37# endif 38 39#else /* no text color */ 40 41#define zap_color(n) 42#define cmap_color(n) 43#define obj_color(n) 44#define mon_color(n) 45#define invis_color(n) 46#define pet_color(c) 47#define warn_color(n) 48#define explode_color(n) 49#endif 50 51#ifdef ROGUE_COLOR 52# if defined(USE_TILES) && defined(MSDOS) 53#define HAS_ROGUE_IBM_GRAPHICS (iflags.IBMgraphics && !iflags.grmode && \ 54 Is_rogue_level(&u.uz)) 55# else 56#define HAS_ROGUE_IBM_GRAPHICS (iflags.IBMgraphics && Is_rogue_level(&u.uz)) 57# endif 58#endif 59 60/*ARGSUSED*/ 61void 62mapglyph(glyph, ochar, ocolor, ospecial, x, y) 63int glyph, *ocolor, x, y; 64int *ochar; 65unsigned *ospecial; 66{ 67 register int offset; 68#if defined(TEXTCOLOR) || defined(ROGUE_COLOR) 69 int color = NO_COLOR; 70#endif 71 uchar ch; 72 unsigned special = 0; 73 74 /* 75 * Map the glyph back to a character and color. 76 * 77 * Warning: For speed, this makes an assumption on the order of 78 * offsets. The order is set in display.h. 79 */ 80 if ((offset = (glyph - GLYPH_WARNING_OFF)) >= 0) { /* a warning flash */ 81 ch = warnsyms[offset]; 82# ifdef ROGUE_COLOR 83 if (HAS_ROGUE_IBM_GRAPHICS) 84 color = NO_COLOR; 85 else 86# endif 87 warn_color(offset); 88 } else if ((offset = (glyph - GLYPH_SWALLOW_OFF)) >= 0) { /* swallow */ 89 /* see swallow_to_glyph() in display.c */ 90 ch = (uchar) showsyms[S_sw_tl + (offset & 0x7)]; 91#ifdef ROGUE_COLOR 92 if (HAS_ROGUE_IBM_GRAPHICS && iflags.use_color) 93 color = NO_COLOR; 94 else 95#endif 96 mon_color(offset >> 3); 97 } else if ((offset = (glyph - GLYPH_ZAP_OFF)) >= 0) { /* zap beam */ 98 /* see zapdir_to_glyph() in display.c */ 99 ch = showsyms[S_vbeam + (offset & 0x3)]; 100#ifdef ROGUE_COLOR 101 if (HAS_ROGUE_IBM_GRAPHICS && iflags.use_color) 102 color = NO_COLOR; 103 else 104#endif 105 zap_color((offset >> 2)); 106 } else if ((offset = (glyph - GLYPH_EXPLODE_OFF)) >= 0) { /* explosion */ 107 ch = showsyms[(offset % MAXEXPCHARS) + S_explode1]; 108 explode_color(offset / MAXEXPCHARS); 109 } else if ((offset = (glyph - GLYPH_CMAP_OFF)) >= 0) { /* cmap */ 110 ch = showsyms[offset]; 111#ifdef ROGUE_COLOR 112 if (HAS_ROGUE_IBM_GRAPHICS && iflags.use_color) { 113 if (offset >= S_vwall && offset <= S_hcdoor) 114 color = CLR_BROWN; 115 else if (offset >= S_arrow_trap && offset <= S_polymorph_trap) 116 color = CLR_MAGENTA; 117 else if (offset == S_corr || offset == S_litcorr) 118 color = CLR_GRAY; 119 else if (offset >= S_room && offset <= S_water) 120 color = CLR_GREEN; 121 else 122 color = NO_COLOR; 123 } else 124#endif 125#ifdef TEXTCOLOR 126 /* provide a visible difference if normal and lit corridor 127 * use the same symbol */ 128 if (iflags.use_color && 129 offset == S_litcorr && ch == showsyms[S_corr]) 130 color = CLR_WHITE; 131 else 132#endif 133 cmap_color(offset); 134 } else if ((offset = (glyph - GLYPH_OBJ_OFF)) >= 0) { /* object */ 135 if (offset == BOULDER && iflags.bouldersym) ch = iflags.bouldersym; 136 else ch = oc_syms[(int)objects[offset].oc_class]; 137#ifdef ROGUE_COLOR 138 if (HAS_ROGUE_IBM_GRAPHICS && iflags.use_color) { 139 switch(objects[offset].oc_class) { 140 case COIN_CLASS: color = CLR_YELLOW; break; 141 case FOOD_CLASS: color = CLR_RED; break; 142 default: color = CLR_BRIGHT_BLUE; break; 143 } 144 } else 145#endif 146 obj_color(offset); 147 } else if ((offset = (glyph - GLYPH_RIDDEN_OFF)) >= 0) { /* mon ridden */ 148 ch = monsyms[(int)mons[offset].mlet]; 149#ifdef ROGUE_COLOR 150 if (HAS_ROGUE_IBM_GRAPHICS) 151 /* This currently implies that the hero is here -- monsters */ 152 /* don't ride (yet...). Should we set it to yellow like in */ 153 /* the monster case below? There is no equivalent in rogue. */ 154 color = NO_COLOR; /* no need to check iflags.use_color */ 155 else 156#endif 157 mon_color(offset); 158 special |= MG_RIDDEN; 159 } else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) { /* a corpse */ 160 ch = oc_syms[(int)objects[CORPSE].oc_class]; 161#ifdef ROGUE_COLOR 162 if (HAS_ROGUE_IBM_GRAPHICS && iflags.use_color) 163 color = CLR_RED; 164 else 165#endif 166 mon_color(offset); 167 special |= MG_CORPSE; 168 } else if ((offset = (glyph - GLYPH_DETECT_OFF)) >= 0) { /* mon detect */ 169 ch = monsyms[(int)mons[offset].mlet]; 170#ifdef ROGUE_COLOR 171 if (HAS_ROGUE_IBM_GRAPHICS) 172 color = NO_COLOR; /* no need to check iflags.use_color */ 173 else 174#endif 175 mon_color(offset); 176 /* Disabled for now; anyone want to get reverse video to work? */ 177 /* is_reverse = TRUE; */ 178 special |= MG_DETECT; 179 } else if ((offset = (glyph - GLYPH_INVIS_OFF)) >= 0) { /* invisible */ 180 ch = DEF_INVISIBLE; 181#ifdef ROGUE_COLOR 182 if (HAS_ROGUE_IBM_GRAPHICS) 183 color = NO_COLOR; /* no need to check iflags.use_color */ 184 else 185#endif 186 invis_color(offset); 187 special |= MG_INVIS; 188 } else if ((offset = (glyph - GLYPH_PET_OFF)) >= 0) { /* a pet */ 189 ch = monsyms[(int)mons[offset].mlet]; 190#ifdef ROGUE_COLOR 191 if (HAS_ROGUE_IBM_GRAPHICS) 192 color = NO_COLOR; /* no need to check iflags.use_color */ 193 else 194#endif 195 pet_color(offset); 196 special |= MG_PET; 197 } else { /* a monster */ 198 ch = monsyms[(int)mons[glyph].mlet]; 199#ifdef ROGUE_COLOR 200 if (HAS_ROGUE_IBM_GRAPHICS && iflags.use_color) { 201 if (x == u.ux && y == u.uy) 202 /* actually player should be yellow-on-gray if in a corridor */ 203 color = CLR_YELLOW; 204 else 205 color = NO_COLOR; 206 } else 207#endif 208 { 209 mon_color(glyph); 210 /* special case the hero for `showrace' option */ 211#ifdef TEXTCOLOR 212 if (iflags.use_color && x == u.ux && y == u.uy && 213 iflags.showrace && !Upolyd) 214 color = HI_DOMESTIC; 215#endif 216 } 217 } 218 219#ifdef TEXTCOLOR 220 /* Turn off color if no color defined, or rogue level w/o PC graphics. */ 221# ifdef REINCARNATION 222# ifdef ASCIIGRAPH 223 if (!has_color(color) || (Is_rogue_level(&u.uz) && !HAS_ROGUE_IBM_GRAPHICS)) 224# else 225 if (!has_color(color) || Is_rogue_level(&u.uz)) 226# endif 227# else 228 if (!has_color(color)) 229# endif 230 color = NO_COLOR; 231#endif 232 233 *ochar = (int)ch; 234 *ospecial = special; 235#ifdef TEXTCOLOR 236 *ocolor = color; 237#endif 238 return; 239} 240 241/*mapglyph.c*/ 242