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