OSDN Git Service

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