1 | /* SCCS Id: @(#)drawing.c 3.3 1999/12/02 */ 2 | /* Copyright (c) NetHack Development Team 1992. */ 3 | /* NetHack may be freely redistributed. See license for details. */ 4 | 5 | #include "hack.h" 6 | #include "tcap.h" 7 | 8 | /* Relevent header information in rm.h and objclass.h. */ 9 | 10 | #ifdef C 11 | #undef C 12 | #endif 13 | 14 | #ifdef TEXTCOLOR 15 | #define C(n) n 16 | #else 17 | #define C(n) 18 | #endif 19 | 20 | #define g_FILLER(symbol) 0 21 | 22 | uchar oc_syms[MAXOCLASSES] = DUMMY; /* the current object display symbols */ 23 | uchar showsyms[MAXPCHARS] = DUMMY; /* the current feature display symbols */ 24 | uchar monsyms[MAXMCLASSES] = DUMMY; /* the current monster display symbols */ 25 | uchar warnsyms[WARNCOUNT] = DUMMY; /* the current warning display symbols */ 26 | 27 | /* Default object class symbols. See objclass.h. */ 28 | const char def_oc_syms[MAXOCLASSES] = { 29 | /* 0*/ '\0', /* placeholder for the "random class" */ 30 | ILLOBJ_SYM, 31 | WEAPON_SYM, 32 | ARMOR_SYM, 33 | RING_SYM, 34 | /* 5*/ AMULET_SYM, 35 | TOOL_SYM, 36 | FOOD_SYM, 37 | POTION_SYM, 38 | SCROLL_SYM, 39 | /*10*/ SPBOOK_SYM, 40 | WAND_SYM, 41 | GOLD_SYM, 42 | GEM_SYM, 43 | ROCK_SYM, 44 | /*15*/ BALL_SYM, 45 | CHAIN_SYM, 46 | VENOM_SYM 47 | }; 48 | 49 | const char *invisexplain = "remembered, unseen, creature"; 50 | 51 | /* Object descriptions. Used in do_look(). */ 52 | const char *objexplain[] = { /* these match def_oc_syms, above */ 53 | /* 0*/ 0, 54 | "strange object", 55 | "weapon", 56 | "suit or piece of armor", 57 | "ring", 58 | /* 5*/ "amulet", 59 | "useful item (pick-axe, key, lamp...)", 60 | "piece of food", 61 | "potion", 62 | "scroll", 63 | /*10*/ "spellbook", 64 | "wand", 65 | "pile of coins", 66 | "gem or rock", 67 | "boulder or statue", 68 | /*15*/ "iron ball", 69 | "iron chain", 70 | "splash of venom" 71 | }; 72 | 73 | /* Object class names. Used in object_detect(). */ 74 | const char *oclass_names[] = { 75 | /* 0*/ 0, 76 | "illegal objects", 77 | "weapons", 78 | "armor", 79 | "rings", 80 | /* 5*/ "amulets", 81 | "tools", 82 | "food", 83 | "potions", 84 | "scrolls", 85 | /*10*/ "spellbooks", 86 | "wands", 87 | "coins", 88 | "rocks", 89 | "large stones", 90 | /*15*/ "iron balls", 91 | "chains", 92 | "venoms" 93 | }; 94 | 95 | /* Default monster class symbols. See monsym.h. */ 96 | const char def_monsyms[MAXMCLASSES] = { 97 | '\0', /* holder */ 98 | DEF_ANT, 99 | DEF_BLOB, 100 | DEF_COCKATRICE, 101 | DEF_DOG, 102 | DEF_EYE, 103 | DEF_FELINE, 104 | DEF_GREMLIN, 105 | DEF_HUMANOID, 106 | DEF_IMP, 107 | DEF_JELLY, /* 10 */ 108 | DEF_KOBOLD, 109 | DEF_LEPRECHAUN, 110 | DEF_MIMIC, 111 | DEF_NYMPH, 112 | DEF_ORC, 113 | DEF_PIERCER, 114 | DEF_QUADRUPED, 115 | DEF_RODENT, 116 | DEF_SPIDER, 117 | DEF_TRAPPER, /* 20 */ 118 | DEF_UNICORN, 119 | DEF_VORTEX, 120 | DEF_WORM, 121 | DEF_XAN, 122 | DEF_LIGHT, 123 | DEF_ZRUTY, 124 | DEF_ANGEL, 125 | DEF_BAT, 126 | DEF_CENTAUR, 127 | DEF_DRAGON, /* 30 */ 128 | DEF_ELEMENTAL, 129 | DEF_FUNGUS, 130 | DEF_GNOME, 131 | DEF_GIANT, 132 | '\0', 133 | DEF_JABBERWOCK, 134 | DEF_KOP, 135 | DEF_LICH, 136 | DEF_MUMMY, 137 | DEF_NAGA, /* 40 */ 138 | DEF_OGRE, 139 | DEF_PUDDING, 140 | DEF_QUANTMECH, 141 | DEF_RUSTMONST, 142 | DEF_SNAKE, 143 | DEF_TROLL, 144 | DEF_UMBER, 145 | DEF_VAMPIRE, 146 | DEF_WRAITH, 147 | DEF_XORN, /* 50 */ 148 | DEF_YETI, 149 | DEF_ZOMBIE, 150 | DEF_HUMAN, 151 | DEF_GHOST, 152 | DEF_GOLEM, 153 | DEF_DEMON, 154 | DEF_EEL, 155 | DEF_LIZARD, 156 | DEF_WORM_TAIL, 157 | DEF_MIMIC_DEF, /* 60 */ 158 | }; 159 | 160 | /* The explanations below are also used when the user gives a string 161 | * for blessed genocide, so no text should wholly contain any later 162 | * text. They should also always contain obvious names (eg. cat/feline). 163 | */ 164 | const char *monexplain[MAXMCLASSES] = { 165 | 0, 166 | "ant or other insect", "blob", "cockatrice", 167 | "dog or other canine", "eye or sphere", "cat or other feline", 168 | "gremlin", "humanoid", "imp or minor demon", 169 | "jelly", "kobold", "leprechaun", 170 | "mimic", "nymph", "orc", 171 | "piercer", "quadruped", "rodent", 172 | "spider", "trapper or lurker above", "unicorn or horse", 173 | "vortex", "worm", "xan or other mythical/fantastic insect", 174 | "light", "zruty", 175 | 176 | "angelic being", "bat or bird", "centaur", 177 | "dragon", "elemental", "fungus or mold", 178 | "gnome", "giant humanoid", 0, 179 | "jabberwock", "Keystone Kop", "lich", 180 | "mummy", "naga", "ogre", 181 | "pudding or ooze", "quantum mechanic", "rust monster or disenchanter", 182 | "snake", "troll", "umber hulk", 183 | "vampire", "wraith", "xorn", 184 | "yeti, ape or other large beast", "zombie", 185 | 186 | "human or elf", "ghost", "golem", 187 | "major demon", "sea monster", "lizard", 188 | "long worm tail", "mimic" 189 | }; 190 | 191 | const struct symdef def_warnsyms[WARNCOUNT] = { 192 | {'0', "unknown creature causing you worry", C(CLR_WHITE)}, /* white warning */ 193 | {'1', "unknown creature causing you concern", C(CLR_RED)}, /* pink warning */ 194 | {'2', "unknown creature causing you anxiety", C(CLR_RED)}, /* red warning */ 195 | {'3', "unknown creature causing you disquiet", C(CLR_RED)}, /* ruby warning */ 196 | {'4', "unknown creature causing you alarm", 197 | C(CLR_MAGENTA)}, /* purple warning */ 198 | {'5', "unknown creature causing you dread", 199 | C(CLR_BRIGHT_MAGENTA)} /* black warning */ 200 | }; 201 | 202 | /* 203 | * Default screen symbols with explanations and colors. 204 | * Note: {ibm|dec|mac}_graphics[] arrays also depend on this symbol order. 205 | */ 206 | const struct symdef defsyms[MAXPCHARS] = { 207 | /* 0*/ {' ', "dark part of a room",C(NO_COLOR)}, /* stone */ 208 | {'|', "wall", C(CLR_GRAY)}, /* vwall */ 209 | {'-', "wall", C(CLR_GRAY)}, /* hwall */ 210 | {'-', "wall", C(CLR_GRAY)}, /* tlcorn */ 211 | {'-', "wall", C(CLR_GRAY)}, /* trcorn */ 212 | {'-', "wall", C(CLR_GRAY)}, /* blcorn */ 213 | {'-', "wall", C(CLR_GRAY)}, /* brcorn */ 214 | {'-', "wall", C(CLR_GRAY)}, /* crwall */ 215 | {'-', "wall", C(CLR_GRAY)}, /* tuwall */ 216 | {'-', "wall", C(CLR_GRAY)}, /* tdwall */ 217 | /*10*/ {'|', "wall", C(CLR_GRAY)}, /* tlwall */ 218 | {'|', "wall", C(CLR_GRAY)}, /* trwall */ 219 | {'.', "doorway", C(CLR_GRAY)}, /* ndoor */ 220 | {'-', "open door", C(CLR_BROWN)}, /* vodoor */ 221 | {'|', "open door", C(CLR_BROWN)}, /* hodoor */ 222 | {'+', "closed door", C(CLR_BROWN)}, /* vcdoor */ 223 | {'+', "closed door", C(CLR_BROWN)}, /* hcdoor */ 224 | {'#', "iron bars", C(HI_METAL)}, /* bars */ 225 | {'#', "tree", C(CLR_GREEN)}, /* tree */ 226 | {'.', "floor of a room",C(CLR_GRAY)}, /* room */ 227 | /*20*/ {'#', "corridor", C(CLR_GRAY)}, /* dark corr */ 228 | {'#', "lit corridor", C(CLR_GRAY)}, /* lit corr */ 229 | {'<', "staircase up", C(CLR_GRAY)}, /* upstair */ 230 | {'>', "staircase down", C(CLR_GRAY)}, /* dnstair */ 231 | {'<', "ladder up", C(CLR_BROWN)}, /* upladder */ 232 | {'>', "ladder down", C(CLR_BROWN)}, /* dnladder */ 233 | {'_', "altar", C(CLR_GRAY)}, /* altar */ 234 | {'|', "grave", C(CLR_GRAY)}, /* grave */ 235 | {'\\', "opulent throne",C(HI_GOLD)}, /* throne */ 236 | #ifdef SINKS 237 | {'#', "sink", C(CLR_GRAY)}, /* sink */ 238 | #else 239 | {'#', "", C(CLR_GRAY)}, /* sink */ 240 | #endif 241 | /*30*/ {'{', "fountain", C(CLR_BLUE)}, /* fountain */ 242 | {'}', "water", C(CLR_BLUE)}, /* pool */ 243 | {'.', "ice", C(CLR_CYAN)}, /* ice */ 244 | {'}', "molten lava", C(CLR_RED)}, /* lava */ 245 | {'.', "lowered drawbridge",C(CLR_BROWN)}, /* vodbridge */ 246 | {'.', "lowered drawbridge",C(CLR_BROWN)}, /* hodbridge */ 247 | {'#', "raised drawbridge",C(CLR_BROWN)},/* vcdbridge */ 248 | {'#', "raised drawbridge",C(CLR_BROWN)},/* hcdbridge */ 249 | {' ', "air", C(CLR_CYAN)}, /* open air */ 250 | {'#', "cloud", C(CLR_GRAY)}, /* [part of] a cloud */ 251 | /*40*/ {'}', "water", C(CLR_BLUE)}, /* under water */ 252 | {'^', "arrow trap", C(HI_METAL)}, /* trap */ 253 | {'^', "dart trap", C(HI_METAL)}, /* trap */ 254 | {'^', "falling rock trap",C(CLR_GRAY)}, /* trap */ 255 | {'^', "squeaky board", C(CLR_BROWN)}, /* trap */ 256 | {'^', "bear trap", C(HI_METAL)}, /* trap */ 257 | {'^', "land mine", C(CLR_RED)}, /* trap */ 258 | {'^', "rolling boulder trap", C(CLR_GRAY)}, /* trap */ 259 | {'^', "sleeping gas trap",C(HI_ZAP)}, /* trap */ 260 | {'^', "rust trap", C(CLR_BLUE)}, /* trap */ 261 | /*50*/ {'^', "fire trap", C(CLR_ORANGE)}, /* trap */ 262 | {'^', "pit", C(CLR_BLACK)}, /* trap */ 263 | {'^', "spiked pit", C(CLR_BLACK)}, /* trap */ 264 | {'^', "hole", C(CLR_BROWN)}, /* trap */ 265 | {'^', "trap door", C(CLR_BROWN)}, /* trap */ 266 | {'^', "teleportation trap", C(CLR_MAGENTA)}, /* trap */ 267 | {'^', "level teleporter", C(CLR_MAGENTA)}, /* trap */ 268 | {'^', "magic portal", C(CLR_BRIGHT_MAGENTA)}, /* trap */ 269 | {'"', "web", C(CLR_GRAY)}, /* web */ 270 | {'^', "statue trap", C(CLR_GRAY)}, /* trap */ 271 | /*60*/ {'^', "magic trap", C(HI_ZAP)}, /* trap */ 272 | {'^', "anti-magic trap field", C(HI_ZAP)}, /* trap */ 273 | {'^', "polymorph trap", C(CLR_BRIGHT_GREEN)}, /* trap */ 274 | {'|', "wall", C(CLR_GRAY)}, /* vbeam */ 275 | {'-', "wall", C(CLR_GRAY)}, /* hbeam */ 276 | {'\\',"wall", C(CLR_GRAY)}, /* lslant */ 277 | {'/', "wall", C(CLR_GRAY)}, /* rslant */ 278 | {'*', "", C(CLR_WHITE)}, /* dig beam */ 279 | {'!', "", C(CLR_WHITE)}, /* camera flash beam */ 280 | {')', "", C(HI_WOOD)}, /* boomerang open left */ 281 | /*70*/ {'(', "", C(HI_WOOD)}, /* boomerang open right */ 282 | {'0', "", C(HI_ZAP)}, /* 4 magic shield symbols */ 283 | {'#', "", C(HI_ZAP)}, 284 | {'@', "", C(HI_ZAP)}, 285 | {'*', "", C(HI_ZAP)}, 286 | {'/', "", C(CLR_GREEN)}, /* swallow top left */ 287 | {'-', "", C(CLR_GREEN)}, /* swallow top center */ 288 | {'\\', "", C(CLR_GREEN)}, /* swallow top right */ 289 | {'|', "", C(CLR_GREEN)}, /* swallow middle left */ 290 | {'|', "", C(CLR_GREEN)}, /* swallow middle right */ 291 | /*80*/ {'\\', "", C(CLR_GREEN)}, /* swallow bottom left */ 292 | {'-', "", C(CLR_GREEN)}, /* swallow bottom center*/ 293 | {'/', "", C(CLR_GREEN)}, /* swallow bottom right */ 294 | {'/', "", C(CLR_ORANGE)}, /* explosion top left */ 295 | {'-', "", C(CLR_ORANGE)}, /* explosion top center */ 296 | {'\\', "", C(CLR_ORANGE)}, /* explosion top right */ 297 | {'|', "", C(CLR_ORANGE)}, /* explosion middle left */ 298 | {' ', "", C(CLR_ORANGE)}, /* explosion middle center*/ 299 | {'|', "", C(CLR_ORANGE)}, /* explosion middle right */ 300 | {'\\', "", C(CLR_ORANGE)}, /* explosion bottom left */ 301 | /*90*/ {'-', "", C(CLR_ORANGE)}, /* explosion bottom center*/ 302 | {'/', "", C(CLR_ORANGE)}, /* explosion bottom right */ 303 | /* 304 | * Note: Additions to this array should be reflected in the 305 | * {ibm,dec,mac}_graphics[] arrays below. 306 | */ 307 | }; 308 | 309 | #undef C 310 | 311 | #ifdef ASCIIGRAPH 312 | 313 | #ifdef PC9800 314 | void NDECL((*ibmgraphics_mode_callback)) = 0; /* set in tty_start_screen() */ 315 | #endif /* PC9800 */ 316 | 317 | static uchar ibm_graphics[MAXPCHARS] = { 318 | /* 0*/ g_FILLER(S_stone), 319 | 0xb3, /* S_vwall: meta-3, vertical rule */ 320 | 0xc4, /* S_hwall: meta-D, horizontal rule */ 321 | 0xda, /* S_tlcorn: meta-Z, top left corner */ 322 | 0xbf, /* S_trcorn: meta-?, top right corner */ 323 | 0xc0, /* S_blcorn: meta-@, bottom left */ 324 | 0xd9, /* S_brcorn: meta-Y, bottom right */ 325 | 0xc5, /* S_crwall: meta-E, cross */ 326 | 0xc1, /* S_tuwall: meta-A, T up */ 327 | 0xc2, /* S_tdwall: meta-B, T down */ 328 | /*10*/ 0xb4, /* S_tlwall: meta-4, T left */ 329 | 0xc3, /* S_trwall: meta-C, T right */ 330 | 0xfa, /* S_ndoor: meta-z, centered dot */ 331 | 0xfe, /* S_vodoor: meta-~, small centered square */ 332 | 0xfe, /* S_hodoor: meta-~, small centered square */ 333 | g_FILLER(S_vcdoor), 334 | g_FILLER(S_hcdoor), 335 | 240, /* S_bars: equivalence symbol */ 336 | 241, /* S_tree: plus or minus symbol */ 337 | 0xfa, /* S_room: meta-z, centered dot */ 338 | /*20*/ 0xb0, /* S_corr: meta-0, light shading */ 339 | 0xb1, /* S_litcorr: meta-1, medium shading */ 340 | g_FILLER(S_upstair), 341 | g_FILLER(S_dnstair), 342 | g_FILLER(S_upladder), 343 | g_FILLER(S_dnladder), 344 | g_FILLER(S_altar), 345 | g_FILLER(S_grave), 346 | g_FILLER(S_throne), 347 | g_FILLER(S_sink), 348 | /*30*/ 0xf4, /* S_fountain: meta-t, integral top half */ 349 | 0xf7, /* S_pool: meta-w, approx. equals */ 350 | 0xfa, /* S_ice: meta-z, centered dot */ 351 | 0xf7, /* S_lava: meta-w, approx. equals */ 352 | 0xfa, /* S_vodbridge: meta-z, centered dot */ 353 | 0xfa, /* S_hodbridge: meta-z, centered dot */ 354 | g_FILLER(S_vcdbridge), 355 | g_FILLER(S_hcdbridge), 356 | g_FILLER(S_air), 357 | g_FILLER(S_cloud), 358 | /*40*/ 0xf7, /* S_water: meta-w, approx. equals */ 359 | g_FILLER(S_arrow_trap), 360 | g_FILLER(S_dart_trap), 361 | g_FILLER(S_falling_rock_trap), 362 | g_FILLER(S_squeaky_board), 363 | g_FILLER(S_bear_trap), 364 | g_FILLER(S_land_mine), 365 | g_FILLER(S_rolling_boulder_trap), 366 | g_FILLER(S_sleeping_gas_trap), 367 | g_FILLER(S_rust_trap), 368 | /*50*/ g_FILLER(S_fire_trap), 369 | g_FILLER(S_pit), 370 | g_FILLER(S_spiked_pit), 371 | g_FILLER(S_hole), 372 | g_FILLER(S_trap_door), 373 | g_FILLER(S_teleportation_trap), 374 | g_FILLER(S_level_teleporter), 375 | g_FILLER(S_magic_portal), 376 | g_FILLER(S_web), 377 | g_FILLER(S_statue_trap), 378 | /*60*/ g_FILLER(S_magic_trap), 379 | g_FILLER(S_anti_magic_trap), 380 | g_FILLER(S_polymorph_trap), 381 | 0xb3, /* S_vbeam: meta-3, vertical rule */ 382 | 0xc4, /* S_hbeam: meta-D, horizontal rule */ 383 | g_FILLER(S_lslant), 384 | g_FILLER(S_rslant), 385 | g_FILLER(S_digbeam), 386 | g_FILLER(S_flashbeam), 387 | g_FILLER(S_boomleft), 388 | /*70*/ g_FILLER(S_boomright), 389 | g_FILLER(S_ss1), 390 | g_FILLER(S_ss2), 391 | g_FILLER(S_ss3), 392 | g_FILLER(S_ss4), 393 | g_FILLER(S_sw_tl), 394 | g_FILLER(S_sw_tc), 395 | g_FILLER(S_sw_tr), 396 | 0xb3, /* S_sw_ml: meta-3, vertical rule */ 397 | 0xb3, /* S_sw_mr: meta-3, vertical rule */ 398 | /*80*/ g_FILLER(S_sw_bl), 399 | g_FILLER(S_sw_bc), 400 | g_FILLER(S_sw_br), 401 | g_FILLER(S_explode1), 402 | g_FILLER(S_explode2), 403 | g_FILLER(S_explode3), 404 | 0xb3, /* S_explode4: meta-3, vertical rule */ 405 | g_FILLER(S_explode5), 406 | 0xb3, /* S_explode6: meta-3, vertical rule */ 407 | g_FILLER(S_explode7), 408 | /*90*/ g_FILLER(S_explode8), 409 | g_FILLER(S_explode9) 410 | }; 411 | #endif /* ASCIIGRAPH */ 412 | 413 | #ifdef TERMLIB 414 | void NDECL((*decgraphics_mode_callback)) = 0; /* set in tty_start_screen() */ 415 | 416 | static uchar dec_graphics[MAXPCHARS] = { 417 | /* 0*/ g_FILLER(S_stone), 418 | 0xf8, /* S_vwall: meta-x, vertical rule */ 419 | 0xf1, /* S_hwall: meta-q, horizontal rule */ 420 | 0xec, /* S_tlcorn: meta-l, top left corner */ 421 | 0xeb, /* S_trcorn: meta-k, top right corner */ 422 | 0xed, /* S_blcorn: meta-m, bottom left */ 423 | 0xea, /* S_brcorn: meta-j, bottom right */ 424 | 0xee, /* S_crwall: meta-n, cross */ 425 | 0xf6, /* S_tuwall: meta-v, T up */ 426 | 0xf7, /* S_tdwall: meta-w, T down */ 427 | /*10*/ 0xf5, /* S_tlwall: meta-u, T left */ 428 | 0xf4, /* S_trwall: meta-t, T right */ 429 | 0xfe, /* S_ndoor: meta-~, centered dot */ 430 | 0xe1, /* S_vodoor: meta-a, solid block */ 431 | 0xe1, /* S_hodoor: meta-a, solid block */ 432 | g_FILLER(S_vcdoor), 433 | g_FILLER(S_hcdoor), 434 | 0xfb, /* S_bars: meta-{, small pi */ 435 | 0xe7, /* S_tree: meta-g, plus-or-minus */ 436 | 0xfe, /* S_room: meta-~, centered dot */ 437 | /*20*/ g_FILLER(S_corr), 438 | g_FILLER(S_litcorr), 439 | g_FILLER(S_upstair), 440 | g_FILLER(S_dnstair), 441 | 0xf9, /* S_upladder: meta-y, greater-than-or-equals */ 442 | 0xfa, /* S_dnladder: meta-z, less-than-or-equals */ 443 | g_FILLER(S_altar), /* 0xc3, \E)3: meta-C, dagger */ 444 | g_FILLER(S_grave), 445 | g_FILLER(S_throne), 446 | g_FILLER(S_sink), 447 | /*30*/ g_FILLER(S_fountain), /* 0xdb, \E)3: meta-[, integral top half */ 448 | 0xe0, /* S_pool: meta-\, diamond */ 449 | 0xfe, /* S_ice: meta-~, centered dot */ 450 | 0xe0, /* S_lava: meta-\, diamond */ 451 | 0xfe, /* S_vodbridge: meta-~, centered dot */ 452 | 0xfe, /* S_hodbridge: meta-~, centered dot */ 453 | g_FILLER(S_vcdbridge), 454 | g_FILLER(S_hcdbridge), 455 | g_FILLER(S_air), 456 | g_FILLER(S_cloud), 457 | /*40*/ 0xe0, /* S_water: meta-\, diamond */ 458 | g_FILLER(S_arrow_trap), 459 | g_FILLER(S_dart_trap), 460 | g_FILLER(S_falling_rock_trap), 461 | g_FILLER(S_squeaky_board), 462 | g_FILLER(S_bear_trap), 463 | g_FILLER(S_land_mine), 464 | g_FILLER(S_rolling_boulder_trap), 465 | g_FILLER(S_sleeping_gas_trap), 466 | g_FILLER(S_rust_trap), 467 | /*50*/ g_FILLER(S_fire_trap), 468 | g_FILLER(S_pit), 469 | g_FILLER(S_spiked_pit), 470 | g_FILLER(S_hole), 471 | g_FILLER(S_trap_door), 472 | g_FILLER(S_teleportation_trap), 473 | g_FILLER(S_level_teleporter), 474 | g_FILLER(S_magic_portal), 475 | g_FILLER(S_web), /* 0xbd, \E)3: meta-=, int'l currency */ 476 | g_FILLER(S_statue_trap), 477 | /*60*/ g_FILLER(S_magic_trap), 478 | g_FILLER(S_anti_magic_trap), 479 | g_FILLER(S_polymorph_trap), 480 | 0xf8, /* S_vbeam: meta-x, vertical rule */ 481 | 0xf1, /* S_hbeam: meta-q, horizontal rule */ 482 | g_FILLER(S_lslant), 483 | g_FILLER(S_rslant), 484 | g_FILLER(S_digbeam), 485 | g_FILLER(S_flashbeam), 486 | g_FILLER(S_boomleft), 487 | /*70*/ g_FILLER(S_boomright), 488 | g_FILLER(S_ss1), 489 | g_FILLER(S_ss2), 490 | g_FILLER(S_ss3), 491 | g_FILLER(S_ss4), 492 | g_FILLER(S_sw_tl), 493 | 0xef, /* S_sw_tc: meta-o, high horizontal line */ 494 | g_FILLER(S_sw_tr), 495 | 0xf8, /* S_sw_ml: meta-x, vertical rule */ 496 | 0xf8, /* S_sw_mr: meta-x, vertical rule */ 497 | /*80*/ g_FILLER(S_sw_bl), 498 | 0xf3, /* S_sw_bc: meta-s, low horizontal line */ 499 | g_FILLER(S_sw_br), 500 | g_FILLER(S_explode1), 501 | 0xef, /* S_explode2: meta-o, high horizontal line */ 502 | g_FILLER(S_explode3), 503 | 0xf8, /* S_explode4: meta-x, vertical rule */ 504 | g_FILLER(S_explode5), 505 | 0xf8, /* S_explode6: meta-x, vertical rule */ 506 | g_FILLER(S_explode7), 507 | /*90*/ 0xf3, /* S_explode8: meta-s, low horizontal line */ 508 | g_FILLER(S_explode9) 509 | }; 510 | #endif /* TERMLIB */ 511 | 512 | #ifdef MAC_GRAPHICS_ENV 513 | static uchar mac_graphics[MAXPCHARS] = { 514 | /* 0*/ g_FILLER(S_stone), 515 | 0xba, /* S_vwall */ 516 | 0xcd, /* S_hwall */ 517 | 0xc9, /* S_tlcorn */ 518 | 0xbb, /* S_trcorn */ 519 | 0xc8, /* S_blcorn */ 520 | 0xbc, /* S_brcorn */ 521 | 0xce, /* S_crwall */ 522 | 0xca, /* S_tuwall */ 523 | 0xcb, /* S_tdwall */ 524 | /*10*/ 0xb9, /* S_tlwall */ 525 | 0xcc, /* S_trwall */ 526 | 0xb0, /* S_ndoor */ 527 | 0xee, /* S_vodoor */ 528 | 0xee, /* S_hodoor */ 529 | 0xef, /* S_vcdoor */ 530 | 0xef, /* S_hcdoor */ 531 | 0xf0, /* S_bars: equivalency symbol */ 532 | 0xf1, /* S_tree: plus-or-minus */ 533 | g_FILLER(S_Room), 534 | /*20*/ 0xB0, /* S_corr */ 535 | g_FILLER(S_litcorr), 536 | g_FILLER(S_upstair), 537 | g_FILLER(S_dnstair), 538 | g_FILLER(S_upladder), 539 | g_FILLER(S_dnladder), 540 | g_FILLER(S_altar), 541 | 0xef, /* S_grave: same as open door */ 542 | g_FILLER(S_throne), 543 | g_FILLER(S_sink), 544 | /*30*/ g_FILLER(S_fountain), 545 | 0xe0, /* S_pool */ 546 | g_FILLER(S_ice), 547 | g_FILLER(S_lava), 548 | g_FILLER(S_vodbridge), 549 | g_FILLER(S_hodbridge), 550 | g_FILLER(S_vcdbridge), 551 | g_FILLER(S_hcdbridge), 552 | g_FILLER(S_air), 553 | g_FILLER(S_cloud), 554 | /*40*/ g_FILLER(S_water), 555 | g_FILLER(S_arrow_trap), 556 | g_FILLER(S_dart_trap), 557 | g_FILLER(S_falling_rock_trap), 558 | g_FILLER(S_squeaky_board), 559 | g_FILLER(S_bear_trap), 560 | g_FILLER(S_land_mine), 561 | g_FILLER(S_rolling_boulder_trap), 562 | g_FILLER(S_sleeping_gas_trap), 563 | g_FILLER(S_rust_trap), 564 | /*50*/ g_FILLER(S_fire_trap), 565 | g_FILLER(S_pit), 566 | g_FILLER(S_spiked_pit), 567 | g_FILLER(S_hole), 568 | g_FILLER(S_trap_door), 569 | g_FILLER(S_teleportation_trap), 570 | g_FILLER(S_level_teleporter), 571 | g_FILLER(S_magic_portal), 572 | g_FILLER(S_web), 573 | g_FILLER(S_statue_trap), 574 | /*60*/ g_FILLER(S_magic_trap), 575 | g_FILLER(S_anti_magic_trap), 576 | g_FILLER(S_polymorph_trap), 577 | g_FILLER(S_vbeam), 578 | g_FILLER(S_hbeam), 579 | g_FILLER(S_lslant), 580 | g_FILLER(S_rslant), 581 | g_FILLER(S_digbeam), 582 | g_FILLER(S_flashbeam), 583 | g_FILLER(S_boomleft), 584 | /*70*/ g_FILLER(S_boomright), 585 | g_FILLER(S_ss1), 586 | g_FILLER(S_ss2), 587 | g_FILLER(S_ss3), 588 | g_FILLER(S_ss4), 589 | g_FILLER(S_sw_tl), 590 | g_FILLER(S_sw_tc), 591 | g_FILLER(S_sw_tr), 592 | g_FILLER(S_sw_ml), 593 | g_FILLER(S_sw_mr), 594 | /*80*/ g_FILLER(S_sw_bl), 595 | g_FILLER(S_sw_bc), 596 | g_FILLER(S_sw_br), 597 | g_FILLER(S_explode1), 598 | g_FILLER(S_explode2), 599 | g_FILLER(S_explode3), 600 | g_FILLER(S_explode4), 601 | g_FILLER(S_explode5), 602 | g_FILLER(S_explode6), 603 | g_FILLER(S_explode7), 604 | /*90*/ g_FILLER(S_explode8), 605 | g_FILLER(S_explode9) 606 | }; 607 | #endif /* MAC_GRAPHICS_ENV */ 608 | 609 | #ifdef PC9800 610 | void NDECL((*ascgraphics_mode_callback)) = 0; /* set in tty_start_screen() */ 611 | #endif 612 | 613 | /* 614 | * Convert the given character to an object class. If the character is not 615 | * recognized, then MAXOCLASSES is returned. Used in invent.c, options.c, 616 | * pickup.c, sp_lev.c, and lev_main.c. 617 | */ 618 | int 619 | def_char_to_objclass(ch) 620 | char ch; 621 | { 622 | int i; 623 | for (i = 1; i < MAXOCLASSES; i++) 624 | if (ch == def_oc_syms[i]) break; 625 | return i; 626 | } 627 | 628 | /* 629 | * Convert a character into a monster class. This returns the _first_ 630 | * match made. If there are are no matches, return MAXMCLASSES. 631 | */ 632 | int 633 | def_char_to_monclass(ch) 634 | char ch; 635 | { 636 | int i; 637 | for (i = 1; i < MAXMCLASSES; i++) 638 | if (def_monsyms[i] == ch) break; 639 | return i; 640 | } 641 | 642 | void 643 | assign_graphics(graph_chars, glth, maxlen, offset) 644 | register uchar *graph_chars; 645 | int glth, maxlen, offset; 646 | { 647 | register int i; 648 | 649 | for (i = 0; i < maxlen; i++) 650 | showsyms[i+offset] = (((i < glth) && graph_chars[i]) ? 651 | graph_chars[i] : defsyms[i+offset].sym); 652 | } 653 | 654 | void 655 | switch_graphics(gr_set_flag) 656 | int gr_set_flag; 657 | { 658 | switch (gr_set_flag) { 659 | default: 660 | case ASCII_GRAPHICS: 661 | assign_graphics((uchar *)0, 0, MAXPCHARS, 0); 662 | #ifdef PC9800 663 | if (ascgraphics_mode_callback) (*ascgraphics_mode_callback)(); 664 | #endif 665 | break; 666 | #ifdef ASCIIGRAPH 667 | case IBM_GRAPHICS: 668 | /* 669 | * Use the nice IBM Extended ASCII line-drawing characters (codepage 437). 670 | * 671 | * OS/2 defaults to a multilingual character set (codepage 850, corresponding 672 | * to the ISO 8859 character set. We should probably do a VioSetCp() call to 673 | * set the codepage to 437. 674 | */ 675 | iflags.IBMgraphics = TRUE; 676 | iflags.DECgraphics = FALSE; 677 | assign_graphics(ibm_graphics, SIZE(ibm_graphics), MAXPCHARS, 0); 678 | #ifdef PC9800 679 | if (ibmgraphics_mode_callback) (*ibmgraphics_mode_callback)(); 680 | #endif 681 | break; 682 | #endif /* ASCIIGRAPH */ 683 | #ifdef TERMLIB 684 | case DEC_GRAPHICS: 685 | /* 686 | * Use the VT100 line drawing character set. 687 | */ 688 | iflags.DECgraphics = TRUE; 689 | iflags.IBMgraphics = FALSE; 690 | assign_graphics(dec_graphics, SIZE(dec_graphics), MAXPCHARS, 0); 691 | if (decgraphics_mode_callback) (*decgraphics_mode_callback)(); 692 | break; 693 | #endif /* TERMLIB */ 694 | #ifdef MAC_GRAPHICS_ENV 695 | case MAC_GRAPHICS: 696 | assign_graphics(mac_graphics, SIZE(mac_graphics), MAXPCHARS, 0); 697 | break; 698 | #endif 699 | } 700 | return; 701 | } 702 | 703 | 704 | #ifdef REINCARNATION 705 | 706 | /* 707 | * saved display symbols for objects & features. 708 | */ 709 | static uchar save_oc_syms[MAXOCLASSES] = DUMMY; 710 | static uchar save_showsyms[MAXPCHARS] = DUMMY; 711 | static uchar save_monsyms[MAXPCHARS] = DUMMY; 712 | 713 | static const uchar r_oc_syms[MAXOCLASSES] = { 714 | /* 0*/ '\0', 715 | ILLOBJ_SYM, 716 | WEAPON_SYM, 717 | ']', /* armor */ 718 | RING_SYM, 719 | /* 5*/ ',', /* amulet */ 720 | TOOL_SYM, 721 | ':', /* food */ 722 | POTION_SYM, 723 | SCROLL_SYM, 724 | /*10*/ SPBOOK_SYM, 725 | WAND_SYM, 726 | GEM_SYM, /* gold -- yes it's the same as gems */ 727 | GEM_SYM, 728 | ROCK_SYM, 729 | /*15*/ BALL_SYM, 730 | CHAIN_SYM, 731 | VENOM_SYM 732 | }; 733 | 734 | # ifdef ASCIIGRAPH 735 | /* Rogue level graphics. Under IBM graphics mode, use the symbols that were 736 | * used for Rogue on the IBM PC. Unfortunately, this can't be completely 737 | * done because some of these are control characters--armor and rings under 738 | * DOS, and a whole bunch of them under Linux. Use the TTY Rogue characters 739 | * for those cases. 740 | */ 741 | static const uchar IBM_r_oc_syms[MAXOCLASSES] = { /* a la EPYX Rogue */ 742 | /* 0*/ '\0', 743 | ILLOBJ_SYM, 744 | # if defined(MSDOS) || defined(WIN32) || defined(OS2) 745 | 0x18, /* weapon: up arrow */ 746 | /* 0x0a, */ ARMOR_SYM, /* armor: Vert rect with o */ 747 | /* 0x09, */ RING_SYM, /* ring: circle with arrow */ 748 | /* 5*/ 0x0c, /* amulet: "female" symbol */ 749 | TOOL_SYM, 750 | 0x05, /* food: club (as in cards) */ 751 | 0xad, /* potion: upside down '!' */ 752 | 0x0e, /* scroll: musical note */ 753 | /*10*/ SPBOOK_SYM, 754 | 0xe7, /* wand: greek tau */ 755 | 0x0f, /* gold: yes it's the same as gems */ 756 | 0x0f, /* gems: fancy '*' */ 757 | # else 758 | ')', /* weapon */ 759 | ARMOR_SYM, /* armor */ 760 | RING_SYM, /* ring */ 761 | /* 5*/ ',', /* amulet */ 762 | TOOL_SYM, 763 | ':', /* food */ 764 | 0xad, /* potion: upside down '!' */ 765 | SCROLL_SYM, /* scroll */ 766 | /*10*/ SPBOOK_SYM, 767 | 0xe7, /* wand: greek tau */ 768 | GEM_SYM, /* gold: yes it's the same as gems */ 769 | GEM_SYM, /* gems */ 770 | # endif 771 | ROCK_SYM, 772 | /*15*/ BALL_SYM, 773 | CHAIN_SYM, 774 | VENOM_SYM 775 | }; 776 | # endif /* ASCIIGRAPH */ 777 | 778 | void 779 | assign_rogue_graphics(is_rlevel) 780 | boolean is_rlevel; 781 | { 782 | /* Adjust graphics display characters on Rogue levels */ 783 | 784 | if (is_rlevel) { 785 | register int i; 786 | 787 | (void) memcpy((genericptr_t)save_showsyms, 788 | (genericptr_t)showsyms, sizeof showsyms); 789 | (void) memcpy((genericptr_t)save_oc_syms, 790 | (genericptr_t)oc_syms, sizeof oc_syms); 791 | (void) memcpy((genericptr_t)save_monsyms, 792 | (genericptr_t)monsyms, sizeof monsyms); 793 | 794 | /* Use a loop: char != uchar on some machines. */ 795 | for (i = 0; i < MAXMCLASSES; i++) 796 | monsyms[i] = def_monsyms[i]; 797 | # ifdef ASCIIGRAPH 798 | if (iflags.IBMgraphics 799 | # if defined(USE_TILES) && defined(MSDOS) 800 | && !iflags.grmode 801 | # endif 802 | ) 803 | monsyms[S_HUMAN] = 0x01; /* smiley face */ 804 | # endif 805 | for (i = 0; i < MAXPCHARS; i++) 806 | showsyms[i] = defsyms[i].sym; 807 | 808 | /* 809 | * Some day if these rogue showsyms get much more extensive than this, 810 | * we may want to create r_showsyms, and IBM_r_showsyms arrays to hold 811 | * all of this info and to simply initialize it via a for() loop like r_oc_syms. 812 | */ 813 | 814 | # ifdef ASCIIGRAPH 815 | if (!iflags.IBMgraphics 816 | # if defined(USE_TILES) && defined(MSDOS) 817 | || iflags.grmode 818 | # endif 819 | ) { 820 | # endif 821 | showsyms[S_vodoor] = showsyms[S_hodoor] = showsyms[S_ndoor] = '+'; 822 | showsyms[S_upstair] = showsyms[S_dnstair] = '%'; 823 | # ifdef ASCIIGRAPH 824 | } else { 825 | /* a la EPYX Rogue */ 826 | showsyms[S_vwall] = 0xba; /* all walls now use */ 827 | showsyms[S_hwall] = 0xcd; /* double line graphics */ 828 | showsyms[S_tlcorn] = 0xc9; 829 | showsyms[S_trcorn] = 0xbb; 830 | showsyms[S_blcorn] = 0xc8; 831 | showsyms[S_brcorn] = 0xbc; 832 | showsyms[S_crwall] = 0xce; 833 | showsyms[S_tuwall] = 0xca; 834 | showsyms[S_tdwall] = 0xcb; 835 | showsyms[S_tlwall] = 0xb9; 836 | showsyms[S_trwall] = 0xcc; 837 | showsyms[S_ndoor] = 0xce; 838 | showsyms[S_vodoor] = 0xce; 839 | showsyms[S_hodoor] = 0xce; 840 | showsyms[S_room] = 0xfa; /* centered dot */ 841 | showsyms[S_corr] = 0xb1; 842 | showsyms[S_litcorr] = 0xb2; 843 | showsyms[S_upstair] = 0xf0; /* Greek Xi */ 844 | showsyms[S_dnstair] = 0xf0; 845 | showsyms[S_arrow_trap] = 0x04; /* diamond (cards) */ 846 | showsyms[S_dart_trap] = 0x04; 847 | showsyms[S_falling_rock_trap] = 0x04; 848 | showsyms[S_squeaky_board] = 0x04; 849 | showsyms[S_bear_trap] = 0x04; 850 | showsyms[S_land_mine] = 0x04; 851 | showsyms[S_rolling_boulder_trap] = 0x04; 852 | showsyms[S_sleeping_gas_trap] = 0x04; 853 | showsyms[S_rust_trap] = 0x04; 854 | showsyms[S_fire_trap] = 0x04; 855 | showsyms[S_pit] = 0x04; 856 | showsyms[S_spiked_pit] = 0x04; 857 | showsyms[S_hole] = 0x04; 858 | showsyms[S_trap_door] = 0x04; 859 | showsyms[S_teleportation_trap] = 0x04; 860 | showsyms[S_level_teleporter] = 0x04; 861 | showsyms[S_magic_portal] = 0x04; 862 | showsyms[S_web] = 0x04; 863 | showsyms[S_statue_trap] = 0x04; 864 | showsyms[S_magic_trap] = 0x04; 865 | showsyms[S_anti_magic_trap] = 0x04; 866 | showsyms[S_polymorph_trap] = 0x04; 867 | } 868 | #endif /* ASCIIGRAPH */ 869 | 870 | for (i = 0; i < MAXOCLASSES; i++) { 871 | #ifdef ASCIIGRAPH 872 | if (iflags.IBMgraphics 873 | # if defined(USE_TILES) && defined(MSDOS) 874 | && !iflags.grmode 875 | # endif 876 | ) 877 | oc_syms[i] = IBM_r_oc_syms[i]; 878 | else 879 | #endif /* ASCIIGRAPH */ 880 | oc_syms[i] = r_oc_syms[i]; 881 | } 882 | #if defined(MSDOS) && defined(USE_TILES) 883 | if (iflags.grmode) tileview(FALSE); 884 | #endif 885 | } else { 886 | (void) memcpy((genericptr_t)showsyms, 887 | (genericptr_t)save_showsyms, sizeof showsyms); 888 | (void) memcpy((genericptr_t)oc_syms, 889 | (genericptr_t)save_oc_syms, sizeof oc_syms); 890 | (void) memcpy((genericptr_t)monsyms, 891 | (genericptr_t)save_monsyms, sizeof monsyms); 892 | #if defined(MSDOS) && defined(USE_TILES) 893 | if (iflags.grmode) tileview(TRUE); 894 | #endif 895 | } 896 | } 897 | #endif /* REINCARNATION */ 898 | 899 | /*drawing.c*/