OSDN Git Service

upgrade to 3.6.2
[jnethack/source.git] / win / share / tilemap.c
1 /* NetHack 3.6  tilemap.c       $NHDT-Date: 1542501042 2018/11/18 00:30:42 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.35 $ */
2 /*      Copyright (c) 2016 by Michael Allison                     */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 /*
6  *      This source file is compiled twice:
7  *      once without TILETEXT defined to make tilemap.{o,obj},
8  *      then again with it defined to produce tiletxt.{o,obj}.
9  */
10
11 #include "hack.h"
12
13 #define Fprintf (void) fprintf
14
15 const char *FDECL(tilename, (int, int));
16 void NDECL(init_tilemap);
17 void FDECL(process_substitutions, (FILE *));
18 boolean FDECL(acceptable_tilename, (int, const char *, const char *));
19
20 #if defined(MICRO) || defined(WIN32)
21 #undef exit
22 #if !defined(MSDOS) && !defined(WIN32)
23 extern void FDECL(exit, (int));
24 #endif
25 #endif
26
27 #if defined(MSDOS) || defined(WIN32) || defined(X11_GRAPHICS)
28 #define STATUES_LOOK_LIKE_MONSTERS
29 #endif
30
31 #define MON_GLYPH 1
32 #define OBJ_GLYPH 2
33 #define OTH_GLYPH 3 /* fortunately unnecessary */
34
35 #define EXTRA_SCROLL_DESCR_COUNT ((SCR_BLANK_PAPER - SCR_STINKING_CLOUD) - 1)
36
37 /* note that the ifdefs here should be the opposite sense from monst.c/
38  * objects.c/rm.h
39  */
40
41 struct conditionals {
42     int sequence, predecessor;
43     const char *name;
44 } conditionals[] = {
45 #ifndef CHARON /* not supported */
46     { MON_GLYPH, PM_HELL_HOUND, "Cerberus" },
47 #endif
48     /* commented out in monst.c at present */
49     { MON_GLYPH, PM_SHOCKING_SPHERE, "beholder" },
50     { MON_GLYPH, PM_BABY_SILVER_DRAGON, "baby shimmering dragon" },
51     { MON_GLYPH, PM_SILVER_DRAGON, "shimmering dragon" },
52     { MON_GLYPH, PM_JABBERWOCK, "vorpal jabberwock" },
53     { MON_GLYPH, PM_VAMPIRE_LORD, "vampire mage" },
54 #ifndef CHARON /* not supported yet */
55     { MON_GLYPH, PM_CROESUS, "Charon" },
56 #endif
57 #ifndef MAIL
58     { MON_GLYPH, PM_FAMINE, "mail daemon" },
59 #endif
60     /* commented out in monst.c at present */
61     { MON_GLYPH, PM_SHAMAN_KARNOV, "Earendil" },
62     { MON_GLYPH, PM_SHAMAN_KARNOV, "Elwing" },
63     /* commented out in monst.c at present */
64     { MON_GLYPH, PM_CHROMATIC_DRAGON, "Goblin King" },
65     { MON_GLYPH, PM_NEANDERTHAL, "High-elf" },
66     /* objects commented out in objects.c at present */
67     { OBJ_GLYPH, SILVER_DRAGON_SCALE_MAIL, "shimmering dragon scale mail" },
68     { OBJ_GLYPH, SILVER_DRAGON_SCALES, "shimmering dragon scales" },
69 /* allow slime mold to look like slice of pizza, since we
70  * don't know what a slime mold should look like when renamed anyway
71  */
72 #ifndef MAIL
73     { OBJ_GLYPH, SCR_STINKING_CLOUD + EXTRA_SCROLL_DESCR_COUNT,
74       "stamped / mail" },
75 #endif
76     { 0, 0, 0 }
77 };
78
79 /*
80  * Some entries in glyph2tile[] should be substituted for on various levels.
81  * The tiles used for the substitute entries will follow the usual ones in
82  * other.til in the order given here, which should have every substitution
83  * for the same set of tiles grouped together.  You will have to change
84  * more code in process_substitutions()/substitute_tiles() if the sets
85  * overlap in the future.
86  */
87 struct substitute {
88     int first_glyph, last_glyph;
89     const char *sub_name; /* for explanations */
90     const char *level_test;
91 } substitutes[] = { { GLYPH_CMAP_OFF + S_vwall, GLYPH_CMAP_OFF + S_trwall,
92                       "mine walls", "In_mines(plev)" },
93                     { GLYPH_CMAP_OFF + S_vwall, GLYPH_CMAP_OFF + S_trwall,
94                       "gehennom walls", "In_hell(plev)" },
95                     { GLYPH_CMAP_OFF + S_vwall, GLYPH_CMAP_OFF + S_trwall,
96                       "knox walls", "Is_knox(plev)" },
97                     { GLYPH_CMAP_OFF + S_vwall, GLYPH_CMAP_OFF + S_trwall,
98                       "sokoban walls", "In_sokoban(plev)" } };
99
100 #ifdef TILETEXT
101
102 /*
103  * entry is the position of the tile within the monsters/objects/other set
104  */
105 const char *
106 tilename(set, entry)
107 int set, entry;
108 {
109     int i, j, condnum, tilenum;
110     static char buf[BUFSZ];
111
112     /* Note:  these initializers don't do anything except guarantee that
113             we're linked properly.
114     */
115     monst_init();
116     objects_init();
117     (void) def_char_to_objclass(']');
118
119     condnum = tilenum = 0;
120
121     for (i = 0; i < NUMMONS; i++) {
122         if (set == MON_GLYPH && tilenum == entry)
123             return mons[i].mname;
124         tilenum++;
125         while (conditionals[condnum].sequence == MON_GLYPH
126                && conditionals[condnum].predecessor == i) {
127             if (set == MON_GLYPH && tilenum == entry)
128                 return conditionals[condnum].name;
129             condnum++;
130             tilenum++;
131         }
132     }
133     if (set == MON_GLYPH && tilenum == entry)
134         return "invisible monster";
135
136     tilenum = 0; /* set-relative number */
137     for (i = 0; i < NUM_OBJECTS; i++) {
138         /* prefer to give the description - that's all the tile's
139          * appearance should reveal */
140         if (set == OBJ_GLYPH && tilenum == entry) {
141             if (!obj_descr[i].oc_descr)
142                 return obj_descr[i].oc_name;
143             if (!obj_descr[i].oc_name)
144                 return obj_descr[i].oc_descr;
145
146             Sprintf(buf, "%s / %s", obj_descr[i].oc_descr,
147                     obj_descr[i].oc_name);
148             return buf;
149         }
150
151         tilenum++;
152         while (conditionals[condnum].sequence == OBJ_GLYPH
153                && conditionals[condnum].predecessor == i) {
154             if (set == OBJ_GLYPH && tilenum == entry)
155                 return conditionals[condnum].name;
156             condnum++;
157             tilenum++;
158         }
159     }
160
161     tilenum = 0; /* set-relative number */
162     for (i = 0; i < (MAXPCHARS - MAXEXPCHARS); i++) {
163         if (set == OTH_GLYPH && tilenum == entry) {
164             if (*defsyms[i].explanation) {
165                 return defsyms[i].explanation;
166             } else {
167                 Sprintf(buf, "cmap %d", tilenum);
168                 return buf;
169             }
170         }
171         tilenum++;
172         while (conditionals[condnum].sequence == OTH_GLYPH
173                && conditionals[condnum].predecessor == i) {
174             if (set == OTH_GLYPH && tilenum == entry)
175                 return conditionals[condnum].name;
176             condnum++;
177             tilenum++;
178         }
179     }
180     /* explosions */
181     tilenum = MAXPCHARS - MAXEXPCHARS;
182     i = entry - tilenum;
183     if (i < (MAXEXPCHARS * EXPL_MAX)) {
184         if (set == OTH_GLYPH) {
185             static const char *explosion_types[] = {
186                 /* hack.h */
187                 "dark", "noxious", "muddy", "wet", "magical", "fiery",
188                 "frosty"
189             };
190             Sprintf(buf, "explosion %s %d", explosion_types[i / MAXEXPCHARS],
191                     i % MAXEXPCHARS);
192             return buf;
193         }
194     }
195     tilenum += (MAXEXPCHARS * EXPL_MAX);
196
197     i = entry - tilenum;
198     if (i < (NUM_ZAP << 2)) {
199         if (set == OTH_GLYPH) {
200             Sprintf(buf, "zap %d %d", i / 4, i % 4);
201             return buf;
202         }
203     }
204     tilenum += (NUM_ZAP << 2);
205
206     i = entry - tilenum;
207     if (i < WARNCOUNT) {
208         if (set == OTH_GLYPH) {
209             Sprintf(buf, "warning %d", i);
210             return buf;
211         }
212     }
213     tilenum += WARNCOUNT;
214
215     for (i = 0; i < SIZE(substitutes); i++) {
216         j = entry - tilenum;
217         if (j <= substitutes[i].last_glyph - substitutes[i].first_glyph) {
218             if (set == OTH_GLYPH) {
219                 Sprintf(buf, "sub %s %d", substitutes[i].sub_name, j);
220                 return buf;
221             }
222         }
223         tilenum += substitutes[i].last_glyph - substitutes[i].first_glyph + 1;
224     }
225
226     Sprintf(buf, "unknown %d %d", set, entry);
227     return buf;
228 }
229
230 #else /* TILETEXT */
231
232 #define TILE_FILE "tile.c"
233
234 #ifdef AMIGA
235 #define SOURCE_TEMPLATE "NH:src/%s"
236 #else
237 #ifdef MAC
238 #define SOURCE_TEMPLATE ":src:%s"
239 #else
240 #define SOURCE_TEMPLATE "../src/%s"
241 #endif
242 #endif
243
244 short tilemap[MAX_GLYPH];
245
246 #ifdef STATUES_LOOK_LIKE_MONSTERS
247 int lastmontile, lastobjtile, lastothtile, laststatuetile;
248 #else
249 int lastmontile, lastobjtile, lastothtile;
250 #endif
251
252 /* Number of tiles for invisible monsters */
253 #define NUM_INVIS_TILES 1
254
255 /*
256  * set up array to map glyph numbers to tile numbers
257  *
258  * assumes tiles are numbered sequentially through monsters/objects/other,
259  * with entries for all supported compilation options
260  *
261  * "other" contains cmap and zaps (the swallow sets are a repeated portion
262  * of cmap), as well as the "flash" glyphs for the new warning system
263  * introduced in 3.3.1.
264  */
265 void
266 init_tilemap()
267 {
268     int i, j, condnum, tilenum;
269     int corpsetile, swallowbase;
270
271     for (i = 0; i < MAX_GLYPH; i++) {
272         tilemap[i] = -1;
273     }
274
275     corpsetile = NUMMONS + NUM_INVIS_TILES + CORPSE;
276     swallowbase = NUMMONS + NUM_INVIS_TILES + NUM_OBJECTS + S_sw_tl;
277
278     /* add number compiled out */
279     for (i = 0; conditionals[i].sequence; i++) {
280         switch (conditionals[i].sequence) {
281         case MON_GLYPH:
282             corpsetile++;
283             swallowbase++;
284             break;
285         case OBJ_GLYPH:
286             if (conditionals[i].predecessor < CORPSE)
287                 corpsetile++;
288             swallowbase++;
289             break;
290         case OTH_GLYPH:
291             if (conditionals[i].predecessor < S_sw_tl)
292                 swallowbase++;
293             break;
294         }
295     }
296
297     condnum = tilenum = 0;
298     for (i = 0; i < NUMMONS; i++) {
299         tilemap[GLYPH_MON_OFF + i] = tilenum;
300         tilemap[GLYPH_PET_OFF + i] = tilenum;
301         tilemap[GLYPH_DETECT_OFF + i] = tilenum;
302         tilemap[GLYPH_RIDDEN_OFF + i] = tilenum;
303         tilemap[GLYPH_BODY_OFF + i] = corpsetile;
304         j = GLYPH_SWALLOW_OFF + 8 * i;
305         tilemap[j] = swallowbase;
306         tilemap[j + 1] = swallowbase + 1;
307         tilemap[j + 2] = swallowbase + 2;
308         tilemap[j + 3] = swallowbase + 3;
309         tilemap[j + 4] = swallowbase + 4;
310         tilemap[j + 5] = swallowbase + 5;
311         tilemap[j + 6] = swallowbase + 6;
312         tilemap[j + 7] = swallowbase + 7;
313         tilenum++;
314         while (conditionals[condnum].sequence == MON_GLYPH
315                && conditionals[condnum].predecessor == i) {
316             condnum++;
317             tilenum++;
318         }
319     }
320     tilemap[GLYPH_INVISIBLE] = tilenum++;
321     lastmontile = tilenum - 1;
322
323     for (i = 0; i < NUM_OBJECTS; i++) {
324         tilemap[GLYPH_OBJ_OFF + i] = tilenum;
325         tilenum++;
326         while (conditionals[condnum].sequence == OBJ_GLYPH
327                && conditionals[condnum].predecessor == i) {
328             condnum++;
329             tilenum++;
330         }
331     }
332     lastobjtile = tilenum - 1;
333
334     for (i = 0; i < (MAXPCHARS - MAXEXPCHARS); i++) {
335         tilemap[GLYPH_CMAP_OFF + i] = tilenum;
336         tilenum++;
337         while (conditionals[condnum].sequence == OTH_GLYPH
338                && conditionals[condnum].predecessor == i) {
339             condnum++;
340             tilenum++;
341         }
342     }
343
344     for (i = 0; i < (MAXEXPCHARS * EXPL_MAX); i++) {
345         tilemap[GLYPH_EXPLODE_OFF + i] = tilenum;
346         tilenum++;
347         while (conditionals[condnum].sequence == OTH_GLYPH
348                && conditionals[condnum].predecessor == (i + MAXPCHARS)) {
349             condnum++;
350             tilenum++;
351         }
352     }
353
354     for (i = 0; i < NUM_ZAP << 2; i++) {
355         tilemap[GLYPH_ZAP_OFF + i] = tilenum;
356         tilenum++;
357         while (conditionals[condnum].sequence == OTH_GLYPH
358                && conditionals[condnum].predecessor == (i + MAXEXPCHARS)) {
359             condnum++;
360             tilenum++;
361         }
362     }
363
364     for (i = 0; i < WARNCOUNT; i++) {
365         tilemap[GLYPH_WARNING_OFF + i] = tilenum;
366         tilenum++;
367     }
368
369 #ifndef STATUES_LOOK_LIKE_MONSTERS
370     /* statue patch: statues still use the same glyph as in vanilla */
371
372     for (i = 0; i < NUMMONS; i++) {
373         tilemap[GLYPH_STATUE_OFF + i] = tilemap[GLYPH_OBJ_OFF + STATUE];
374     }
375 #endif
376
377     lastothtile = tilenum - 1;
378
379 #ifdef STATUES_LOOK_LIKE_MONSTERS
380     /* skip over the substitutes to get to the grayscale statues */
381     for (i = 0; i < SIZE(substitutes); i++) {
382         tilenum += substitutes[i].last_glyph - substitutes[i].first_glyph + 1;
383     }
384
385     /* statue patch: statues look more like the monster */
386     condnum = 0; /* doing monsters again, so reset */
387     for (i = 0; i < NUMMONS; i++) {
388         tilemap[GLYPH_STATUE_OFF + i] = tilenum;
389         tilenum++;
390         while (conditionals[condnum].sequence == MON_GLYPH
391                && conditionals[condnum].predecessor == i) {
392             condnum++;
393             tilenum++;
394         }
395     }
396     laststatuetile = tilenum - 1;
397 #endif
398 }
399
400 const char *prolog[] = { "", "void", "substitute_tiles(plev)",
401                          "d_level *plev;", "{", "    int i;", "" };
402
403 const char *epilog[] = { "    return;", "}" };
404
405 /* write out the substitutions in an easily-used form. */
406 void
407 process_substitutions(ofp)
408 FILE *ofp;
409 {
410     static const char Dent[] = "    "; /* 4 space indentation */
411     int i, j, k, span, start;
412
413     Fprintf(ofp, "\n");
414
415     j = 0; /* unnecessary */
416     span = -1;
417     for (i = 0; i < SIZE(substitutes); i++) {
418         if (i == 0 || substitutes[i].first_glyph != substitutes[j].first_glyph
419             || substitutes[i].last_glyph != substitutes[j].last_glyph) {
420             j = i;
421             span++;
422             Fprintf(ofp, "short std_tiles%d[] = { ", span);
423             for (k = substitutes[i].first_glyph;
424                  k < substitutes[i].last_glyph; k++)
425                 Fprintf(ofp, "%d, ", tilemap[k]);
426             Fprintf(ofp, "%d };\n", tilemap[substitutes[i].last_glyph]);
427         }
428     }
429
430     for (i = 0; i < SIZE(prolog); i++) {
431         Fprintf(ofp, "%s\n", prolog[i]);
432     }
433     j = -1;
434     span = -1;
435     start = lastothtile + 1;
436     for (i = 0; i < SIZE(substitutes); i++) {
437         if (i == 0 || substitutes[i].first_glyph != substitutes[j].first_glyph
438             || substitutes[i].last_glyph != substitutes[j].last_glyph) {
439             if (i != 0) { /* finish previous span */
440                 Fprintf(ofp, "%s} else {\n", Dent);
441                 Fprintf(ofp, "%s%sfor (i = %d; i <= %d; i++)\n", Dent, Dent,
442                         substitutes[j].first_glyph, substitutes[j].last_glyph);
443                 Fprintf(ofp, "%s%s%sglyph2tile[i] = std_tiles%d[i - %d];\n",
444                         Dent, Dent, Dent, span, substitutes[j].first_glyph);
445                 Fprintf(ofp, "%s}\n\n", Dent);
446             }
447             j = i;
448             span++;
449         }
450         Fprintf(ofp, "%s%sif (%s) {\n", Dent, (i == j) ? "" : "} else ",
451                 substitutes[i].level_test);
452         Fprintf(ofp, "%s%sfor (i = %d; i <= %d; i++)\n", Dent, Dent,
453                 substitutes[i].first_glyph, substitutes[i].last_glyph);
454         Fprintf(ofp, "%s%s%sglyph2tile[i] = %d + i - %d;\n",
455                 Dent, Dent, Dent, start, substitutes[i].first_glyph);
456         start += substitutes[i].last_glyph - substitutes[i].first_glyph + 1;
457     }
458     /* finish last span */
459     Fprintf(ofp, "%s} else {\n", Dent);
460     Fprintf(ofp, "%s%sfor (i = %d; i <= %d; i++)\n", Dent, Dent,
461             substitutes[j].first_glyph, substitutes[j].last_glyph);
462     Fprintf(ofp, "%s%s%sglyph2tile[i] = std_tiles%d[i - %d];\n",
463             Dent, Dent, Dent, span, substitutes[j].first_glyph);
464     Fprintf(ofp, "%s}\n", Dent);
465
466     for (i = 0; i < SIZE(epilog); i++) {
467         Fprintf(ofp, "%s\n", epilog[i]);
468     }
469
470     lastothtile = start - 1;
471 #ifdef STATUES_LOOK_LIKE_MONSTERS
472     start = laststatuetile + 1;
473 #endif
474     Fprintf(ofp, "\nint total_tiles_used = %d;\n", start);
475 }
476
477 int
478 main()
479 {
480     register int i;
481     char filename[30];
482     FILE *ofp;
483
484     init_tilemap();
485
486     /*
487      * create the source file, "tile.c"
488      */
489     Sprintf(filename, SOURCE_TEMPLATE, TILE_FILE);
490     if (!(ofp = fopen(filename, "w"))) {
491         perror(filename);
492         exit(EXIT_FAILURE);
493     }
494     Fprintf(ofp,
495             "/* This file is automatically generated.  Do not edit. */\n");
496     Fprintf(ofp, "\n#include \"hack.h\"\n");
497     Fprintf(ofp, "\nshort glyph2tile[MAX_GLYPH] = {\n");
498
499     for (i = 0; i < MAX_GLYPH; i++) {
500         Fprintf(ofp, " %4d,", tilemap[i]);
501         if ((i % 12) == 11 || i == MAX_GLYPH - 1)
502             Fprintf(ofp, "\n");
503     }
504     Fprintf(ofp, "};\n");
505
506     process_substitutions(ofp);
507
508     Fprintf(ofp, "\n#define MAXMONTILE %d\n", lastmontile);
509     Fprintf(ofp, "#define MAXOBJTILE %d\n", lastobjtile);
510     Fprintf(ofp, "#define MAXOTHTILE %d\n", lastothtile);
511 #ifdef STATUES_LOOK_LIKE_MONSTERS
512     Fprintf(ofp, "/* #define MAXSTATUETILE %d */\n", laststatuetile);
513 #endif
514     Fprintf(ofp, "\n/*tile.c*/\n");
515
516     (void) fclose(ofp);
517     exit(EXIT_SUCCESS);
518     /*NOTREACHED*/
519     return 0;
520 }
521
522 #endif /* TILETEXT */
523
524 struct {
525     int idx;
526     const char *betterlabel;
527     const char *expectedlabel;
528 } altlabels[] = {
529 {S_stone,    "dark part of a room", "dark part of a room"},
530 {S_vwall,    "vertical wall", "wall"},
531 {S_hwall,    "horizontal wall", "wall"},
532 {S_tlcorn,   "top left corner wall", "wall"},
533 {S_trcorn,   "top right corner wall", "wall"},
534 {S_blcorn,   "bottom left corner wall", "wall"},
535 {S_brcorn,   "bottom right corner wall", "wall"},
536 {S_crwall,   "cross wall", "wall"},
537 {S_tuwall,   "tuwall", "wall"},
538 {S_tdwall,   "tdwall", "wall"},
539 {S_tlwall,   "tlwall", "wall"},
540 {S_trwall,   "trwall", "wall"},
541 {S_ndoor,    "no door", "doorway"},
542 {S_vodoor,   "vertical open door", "open door"},
543 {S_hodoor,   "horizontal open door", "open door"},
544 {S_vcdoor,   "vertical closed door", "closed door"},
545 {S_hcdoor,   "horizontal closed door", "closed door"},
546 {S_bars,     "iron bars", "iron bars"},
547 {S_tree,     "tree", "tree"},
548 {S_room,     "room", "floor of a room"},
549 {S_darkroom, "darkroom", "dark part of a room"},
550 {S_corr,     "corridor", "corridor"},
551 {S_litcorr,  "lit corridor", "lit corridor"},
552 {S_upstair,  "up stairs", "staircase up"},
553 {S_dnstair,  "down stairs", "staircase down"},
554 {S_upladder, "up ladder", "ladder up"},
555 {S_dnladder, "down ladder", "ladder down"},
556 {S_altar,    "altar", "altar"},
557 {S_grave,    "grave", "grave"},
558 {S_throne,   "throne", "opulent throne"},
559 {S_sink,     "sink", "sink"},
560 {S_fountain, "fountain", "fountain"},
561 {S_pool,     "pool", "water"},
562 {S_ice,      "ice", "ice"},
563 {S_lava,     "lava", "molten lava"},
564 {S_vodbridge, "vertical open drawbridge", "lowered drawbridge"},
565 {S_hodbridge, "horizontal open drawbridge", "lowered drawbridge"},
566 {S_vcdbridge, "vertical closed drawbridge", "raised drawbridge"},
567 {S_hcdbridge, "horizontal closed drawbridge", "raised drawbridge"},
568 {S_air,      "air", "air"},
569 {S_cloud,    "cloud", "cloud"},
570 {S_water,    "water", "water"},
571 {S_arrow_trap,           "arrow trap", "arrow trap"},
572 {S_dart_trap,            "dart trap", "dart trap"},
573 {S_falling_rock_trap,    "falling rock trap", "falling rock trap"},
574 {S_squeaky_board,        "squeaky board", "squeaky board"},
575 {S_bear_trap,            "bear trap", "bear trap"},
576 {S_land_mine,            "land mine", "land mine"},
577 {S_rolling_boulder_trap, "rolling boulder trap", "rolling boulder trap"},
578 {S_sleeping_gas_trap,    "sleeping gas trap", "sleeping gas trap"},
579 {S_rust_trap,            "rust trap", "rust trap"},
580 {S_fire_trap,            "fire trap", "fire trap"},
581 {S_pit,                  "pit", "pit"},
582 {S_spiked_pit,           "spiked pit", "spiked pit"},
583 {S_hole,                 "hole", "hole"},
584 {S_trap_door,            "trap door", "trap door"},
585 {S_teleportation_trap,   "teleportation trap", "teleportation trap"},
586 {S_level_teleporter,     "level teleporter", "level teleporter"},
587 {S_magic_portal,         "magic portal", "magic portal"},
588 {S_web,                  "web", "web"},
589 {S_statue_trap,          "statue trap", "statue trap"},
590 {S_magic_trap,           "magic trap", "magic trap"},
591 {S_anti_magic_trap,      "anti magic trap", "anti-magic field"},
592 {S_polymorph_trap,       "polymorph trap", "polymorph trap"},
593 {S_vibrating_square,     "vibrating square", "vibrating square"},
594 {S_vbeam,    "vertical beam", "cmap 65"},
595 {S_hbeam,    "horizontal beam", "cmap 66"},
596 {S_lslant,   "left slant beam", "cmap 67"},
597 {S_rslant,   "right slant beam", "cmap 68"},
598 {S_digbeam,  "dig beam", "cmap 69"},
599 {S_flashbeam, "flash beam", "cmap 70"},
600 {S_boomleft, "boom left", "cmap 71"},
601 {S_boomright, "boom right", "cmap 72"},
602 {S_ss1,      "shield1", "cmap 73"},
603 {S_ss2,      "shield2", "cmap 74"},
604 {S_ss3,      "shield3", "cmap 75"},
605 {S_ss4,      "shield4", "cmap 76"},
606 {S_poisoncloud, "poison cloud", "poison cloud"},
607 {S_goodpos,  "valid position", "valid position"},
608 {S_sw_tl,    "swallow top left", "cmap 79"},
609 {S_sw_tc,    "swallow top center", "cmap 80"},
610 {S_sw_tr,    "swallow top right", "cmap 81"},
611 {S_sw_ml,    "swallow middle left", "cmap 82"},
612 {S_sw_mr,    "swallow middle right", "cmap 83"},
613 {S_sw_bl,    "swallow bottom left ", "cmap 84"},
614 {S_sw_bc,    "swallow bottom center", "cmap 85"},
615 {S_sw_br,    "swallow bottom right", "cmap 86"},
616 {S_explode1, "explosion top left", "explosion dark 0"},
617 {S_explode2, "explosion top centre", "explosion dark 1"},
618 {S_explode3, "explosion top right", "explosion dark 2"},
619 {S_explode4, "explosion middle left", "explosion dark 3"},
620 {S_explode5, "explosion middle center", "explosion dark 4"},
621 {S_explode6, "explosion middle right", "explosion dark 5"},
622 {S_explode7, "explosion bottom left", "explosion dark 6"},
623 {S_explode8, "explosion bottom center", "explosion dark 7"},
624 {S_explode9, "explosion bottom right", "explosion dark 8"},
625 };
626
627 boolean
628 acceptable_tilename(idx, encountered, expected)
629 int idx;
630 const char *encountered, *expected;
631 {
632     if (idx >= 0 && idx < SIZE(altlabels)) {
633         if (!strcmp(altlabels[idx].expectedlabel, expected)) {
634             if (!strcmp(altlabels[idx].betterlabel, encountered))
635                 return TRUE;
636         }
637     }
638     return FALSE;
639 }
640
641 /*tilemap.c*/