| 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 | |
|---|
| 12 | int 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*/ |
|---|
| 61 | void |
|---|
| 62 | mapglyph(glyph, ochar, ocolor, ospecial, x, y) |
|---|
| 63 | int glyph, *ocolor, x, y; |
|---|
| 64 | int *ochar; |
|---|
| 65 | unsigned *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 && offset != S_darkroom) |
|---|
| 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 | /* use inverse video for multiple items */ |
|---|
| 148 | if (level.objects[x][y] && |
|---|
| 149 | level.objects[x][y]->nexthere) { |
|---|
| 150 | special |= MG_INVERSE; |
|---|
| 151 | } |
|---|
| 152 | } else if ((offset = (glyph - GLYPH_RIDDEN_OFF)) >= 0) { /* mon ridden */ |
|---|
| 153 | ch = monsyms[(int)mons[offset].mlet]; |
|---|
| 154 | #ifdef ROGUE_COLOR |
|---|
| 155 | if (HAS_ROGUE_IBM_GRAPHICS) |
|---|
| 156 | /* This currently implies that the hero is here -- monsters */ |
|---|
| 157 | /* don't ride (yet...). Should we set it to yellow like in */ |
|---|
| 158 | /* the monster case below? There is no equivalent in rogue. */ |
|---|
| 159 | color = NO_COLOR; /* no need to check iflags.use_color */ |
|---|
| 160 | else |
|---|
| 161 | #endif |
|---|
| 162 | mon_color(offset); |
|---|
| 163 | special |= MG_RIDDEN; |
|---|
| 164 | } else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) { /* a corpse */ |
|---|
| 165 | ch = oc_syms[(int)objects[CORPSE].oc_class]; |
|---|
| 166 | #ifdef ROGUE_COLOR |
|---|
| 167 | if (HAS_ROGUE_IBM_GRAPHICS && iflags.use_color) |
|---|
| 168 | color = CLR_RED; |
|---|
| 169 | else |
|---|
| 170 | #endif |
|---|
| 171 | mon_color(offset); |
|---|
| 172 | special |= MG_CORPSE; |
|---|
| 173 | /* use inverse video for multiple items */ |
|---|
| 174 | if (level.objects[x][y] && |
|---|
| 175 | level.objects[x][y]->nexthere) { |
|---|
| 176 | special |= MG_INVERSE; |
|---|
| 177 | } |
|---|
| 178 | } else if ((offset = (glyph - GLYPH_DETECT_OFF)) >= 0) { /* mon detect */ |
|---|
| 179 | ch = monsyms[(int)mons[offset].mlet]; |
|---|
| 180 | #ifdef ROGUE_COLOR |
|---|
| 181 | if (HAS_ROGUE_IBM_GRAPHICS) |
|---|
| 182 | color = NO_COLOR; /* no need to check iflags.use_color */ |
|---|
| 183 | else |
|---|
| 184 | #endif |
|---|
| 185 | mon_color(offset); |
|---|
| 186 | /* Disabled for now; anyone want to get reverse video to work? */ |
|---|
| 187 | /* is_reverse = TRUE; */ |
|---|
| 188 | special |= MG_DETECT; |
|---|
| 189 | } else if ((offset = (glyph - GLYPH_INVIS_OFF)) >= 0) { /* invisible */ |
|---|
| 190 | ch = DEF_INVISIBLE; |
|---|
| 191 | #ifdef ROGUE_COLOR |
|---|
| 192 | if (HAS_ROGUE_IBM_GRAPHICS) |
|---|
| 193 | color = NO_COLOR; /* no need to check iflags.use_color */ |
|---|
| 194 | else |
|---|
| 195 | #endif |
|---|
| 196 | invis_color(offset); |
|---|
| 197 | special |= MG_INVIS; |
|---|
| 198 | } else if ((offset = (glyph - GLYPH_PET_OFF)) >= 0) { /* a pet */ |
|---|
| 199 | ch = monsyms[(int)mons[offset].mlet]; |
|---|
| 200 | #ifdef ROGUE_COLOR |
|---|
| 201 | if (HAS_ROGUE_IBM_GRAPHICS) |
|---|
| 202 | color = NO_COLOR; /* no need to check iflags.use_color */ |
|---|
| 203 | else |
|---|
| 204 | #endif |
|---|
| 205 | pet_color(offset); |
|---|
| 206 | special |= MG_PET; |
|---|
| 207 | } else { /* a monster */ |
|---|
| 208 | ch = monsyms[(int)mons[glyph].mlet]; |
|---|
| 209 | #ifdef ROGUE_COLOR |
|---|
| 210 | if (HAS_ROGUE_IBM_GRAPHICS && iflags.use_color) { |
|---|
| 211 | if (x == u.ux && y == u.uy) |
|---|
| 212 | /* actually player should be yellow-on-gray if in a corridor */ |
|---|
| 213 | color = CLR_YELLOW; |
|---|
| 214 | else |
|---|
| 215 | color = NO_COLOR; |
|---|
| 216 | } else |
|---|
| 217 | #endif |
|---|
| 218 | { |
|---|
| 219 | mon_color(glyph); |
|---|
| 220 | /* special case the hero for `showrace' option */ |
|---|
| 221 | #ifdef TEXTCOLOR |
|---|
| 222 | if (iflags.use_color && x == u.ux && y == u.uy && |
|---|
| 223 | iflags.showrace && !Upolyd) |
|---|
| 224 | color = HI_DOMESTIC; |
|---|
| 225 | #endif |
|---|
| 226 | } |
|---|
| 227 | } |
|---|
| 228 | |
|---|
| 229 | #ifdef TEXTCOLOR |
|---|
| 230 | /* Turn off color if no color defined, or rogue level w/o PC graphics. */ |
|---|
| 231 | # ifdef REINCARNATION |
|---|
| 232 | # ifdef ASCIIGRAPH |
|---|
| 233 | if (!has_color(color) || (Is_rogue_level(&u.uz) && !HAS_ROGUE_IBM_GRAPHICS)) |
|---|
| 234 | # else |
|---|
| 235 | if (!has_color(color) || Is_rogue_level(&u.uz)) |
|---|
| 236 | # endif |
|---|
| 237 | # else |
|---|
| 238 | if (!has_color(color)) |
|---|
| 239 | # endif |
|---|
| 240 | color = NO_COLOR; |
|---|
| 241 | #endif |
|---|
| 242 | |
|---|
| 243 | *ochar = (int)ch; |
|---|
| 244 | *ospecial = special; |
|---|
| 245 | #ifdef TEXTCOLOR |
|---|
| 246 | *ocolor = color; |
|---|
| 247 | #endif |
|---|
| 248 | return; |
|---|
| 249 | } |
|---|
| 250 | |
|---|
| 251 | /*mapglyph.c*/ |
|---|