enlightenment for armor's effect on spell casting
[NetHack.git] / win / share / tilemap.c
bloba28cd8c76bd61ae7ce046374a7978299cde9f139
1 /* NetHack 3.7 tilemap.c $NHDT-Date: 1737720923 2025/01/24 04:15:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.87 $ */
2 /* Copyright (c) 2016 by Michael Allison */
3 /* NetHack may be freely redistributed. See license for details. */
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 */
11 #if 0
12 #include "config.h"
13 /* #include "onames.h" */
14 #include "permonst.h"
15 #include "objclass.h"
16 /* #include "pm.h" */
17 #include "sym.h"
18 #include "rm.h"
19 #else
20 #include "hack.h"
21 #endif
23 #ifdef Snprintf
24 #undef Snprintf
25 #endif
26 #define Snprintf(str, size, ...) \
27 nh_snprintf(__func__, __LINE__, str, size, __VA_ARGS__)
29 #ifdef MONITOR_HEAP
30 /* with heap monitoring enabled, free(ptr) is a macro which expands to
31 nhfree(ptr,__FILE__,__LINE__); since tilemap doesn't link with
32 src/alloc.o it doesn't have access to nhfree(); use actual free */
33 #undef free
34 #endif
36 #define Fprintf (void) fprintf
39 * Defining OBTAIN_TILEMAP to get a listing of the tile-mappings
40 * for debugging purposes requires that your link to produce
41 * the tilemap utility must also include:
42 * objects.o, monst.o drawing.o
44 #define OBTAIN_TILEMAP
46 #if defined(OBTAIN_TILEMAP) && !defined(TILETEXT)
47 FILE *tilemap_file;
48 #endif
50 #if defined(MICRO) || defined(WIN32)
51 #undef exit
52 #if !defined(MSDOS) && !defined(WIN32)
53 extern void exit(int);
54 #endif
55 #endif
57 struct {
58 int idx;
59 const char *tilelabel;
60 const char *expectedlabel;
61 } altlabels[MAXPCHARS + 1] = {
62 #define PCHAR_TILES
63 #include "defsym.h"
64 #undef PCHAR_TILES
65 { 0, 0, 0 }
68 enum {MON_GLYPH, OBJ_GLYPH, OTH_GLYPH, TERMINATOR = -1};
69 #define EXTRA_SCROLL_DESCR_COUNT ((SCR_BLANK_PAPER - SCR_STINKING_CLOUD) - 1)
70 const char *altar_text[] = {
71 "unaligned", "chaotic", "neutral", "lawful", "other altar",
73 enum wall_levels { main_dungeon, mines, gehennom, knox, sokoban };
75 int wall_offsets[] = {
76 GLYPH_CMAP_MAIN_OFF, GLYPH_CMAP_MINES_OFF,
77 GLYPH_CMAP_GEH_OFF, GLYPH_CMAP_KNOX_OFF,
78 GLYPH_CMAP_SOKO_OFF,
80 const char *wall_texts[] = {
81 "main walls", "mines walls", "gehennom walls",
82 "knox walls", "sokoban walls",
84 const char *walldesc[] = {
85 "vertical", "horizontal", "tlcorn", "trcorn", "blcorn", "brcorn",
86 "cross wall", "tuwall", "tdwall", "tlwall", "trwall",
89 int expl_offsets[] = {
90 GLYPH_EXPLODE_DARK_OFF, GLYPH_EXPLODE_NOXIOUS_OFF,
91 GLYPH_EXPLODE_MUDDY_OFF, GLYPH_EXPLODE_WET_OFF,
92 GLYPH_EXPLODE_MAGICAL_OFF, GLYPH_EXPLODE_FIERY_OFF,
93 GLYPH_EXPLODE_FROSTY_OFF,
95 const char *expl_texts[] = {
96 "dark", "noxious", "muddy", "wet", "magical", "fiery", "frosty",
99 const char *zap_texts[] = {
100 "missile", "fire", "frost", "sleep",
101 "death", "lightning", "poison gas", "acid",
104 enum tilesrc { monsters_file, objects_file, other_file, generated };
105 const char *tilesrc_texts[] = {
106 "monsters.txt", "objects.txt", "other.txt", "generated",
109 struct tilemap_t {
110 short tilenum;
111 #if defined(OBTAIN_TILEMAP)
112 char name[127];
113 int glyph;
114 #endif
115 } tilemap[MAX_GLYPH];
117 #define MAX_TILENAM 256
118 /* List of tiles encountered and their usage */
119 struct tiles_used {
120 int tilenum;
121 enum tilesrc src;
122 int file_entry;
123 char tilenam[MAX_TILENAM];
124 char references[1024];
126 struct tiles_used *tilelist[2500] = { 0 };
128 /* Some special tiles used for init of some things */
129 int TILE_stone = 0, /* will get set to correct tile later */
130 TILE_unexplored = 0, /* will get set to correct tile later */
131 TILE_nothing = 0, /* will get set to correct tile later */
132 TILE_corr = 0; /* will get set to correct tile later; X11 uses it */
134 /* prototypes for functions in this file */
135 const char *tilename(int, const int, int);
136 void init_tilemap(void);
137 void process_substitutions(FILE *);
138 boolean acceptable_tilename(int, int, const char *, const char *);
139 #if defined(OBTAIN_TILEMAP)
140 void precheck(int offset, const char *glyphtype);
141 void add_tileref(int n, int glyphref, enum tilesrc src, int tile_file_entry,
142 const char *nam, const char *prefix);
143 void dump_tilerefs(FILE *fp);
144 void free_tilerefs(void);
145 #endif
147 /* note that the ifdefs here should be the opposite sense from monst.c/
148 * objects.c/rm.h
151 struct conditionals_t {
152 int sequence, predecessor;
153 const char *name;
154 } conditionals[] = {
155 #ifndef CHARON /* not supported */
156 { MON_GLYPH, PM_HELL_HOUND, "Cerberus" },
157 #endif
158 /* commented out in monst.c at present */
159 { MON_GLYPH, PM_SHOCKING_SPHERE, "beholder" },
160 { MON_GLYPH, PM_BABY_SILVER_DRAGON, "baby shimmering dragon" },
161 { MON_GLYPH, PM_SILVER_DRAGON, "shimmering dragon" },
162 { MON_GLYPH, PM_JABBERWOCK, "vorpal jabberwock" },
163 { MON_GLYPH, PM_VAMPIRE_LEADER, "vampire mage" },
164 #ifndef CHARON /* not supported yet */
165 { MON_GLYPH, PM_CROESUS, "Charon" },
166 #endif
167 #ifndef MAIL_STRUCTURES
168 { MON_GLYPH, PM_FAMINE, "mail daemon" },
169 #endif
170 /* commented out in monst.c at present */
171 { MON_GLYPH, PM_SHAMAN_KARNOV, "Earendil" },
172 { MON_GLYPH, PM_SHAMAN_KARNOV, "Elwing" },
173 /* commented out in monst.c at present */
174 { MON_GLYPH, PM_CHROMATIC_DRAGON, "Goblin King" },
175 { MON_GLYPH, PM_NEANDERTHAL, "High-elf" },
176 /* objects commented out in objects.c at present */
177 { OBJ_GLYPH, SILVER_DRAGON_SCALE_MAIL, "shimmering dragon scale mail" },
178 { OBJ_GLYPH, SILVER_DRAGON_SCALES, "shimmering dragon scales" },
179 /* allow slime mold to look like slice of pizza, since we
180 * don't know what a slime mold should look like when renamed anyway
182 #ifndef MAIL_STRUCTURES
183 { OBJ_GLYPH, SCR_STINKING_CLOUD + EXTRA_SCROLL_DESCR_COUNT,
184 "stamped / mail" },
185 #endif
186 { TERMINATOR, 0, 0 }
189 #if defined(TILETEXT) || defined(OBTAIN_TILEMAP)
191 * file_entry is the position of the tile within the monsters/objects/other set
193 const char *
194 tilename(int set, const int file_entry, int gend UNUSED)
196 int i, k, cmap, condnum, tilenum;
197 static char buf[BUFSZ];
198 #if 0
199 int offset, gendnum;
200 #endif
201 (void) def_char_to_objclass(']');
203 tilenum = 0;
205 buf[0] = '\0';
206 if (set == MON_GLYPH) {
207 for (i = 0; i < NUMMONS; i++) {
208 if (tilenum == file_entry) {
209 if (mons[i].pmnames[MALE])
210 Snprintf(buf, sizeof buf, "%s {%s}",
211 mons[i].pmnames[NEUTRAL], mons[i].pmnames[MALE]);
212 else
213 Snprintf(buf, sizeof buf, "%s", mons[i].pmnames[NEUTRAL]);
214 return buf;
216 tilenum++;
217 if (tilenum == file_entry) {
218 if (mons[i].pmnames[FEMALE])
219 Snprintf(buf, sizeof buf, "%s {%s}",
220 mons[i].pmnames[NEUTRAL],
221 mons[i].pmnames[FEMALE]);
222 else
223 Snprintf(buf, sizeof buf, "%s", mons[i].pmnames[NEUTRAL]);
224 return buf;
226 for (condnum = 0; conditionals[condnum].sequence != -1;
227 ++condnum) {
228 if (conditionals[condnum].sequence == MON_GLYPH
229 && conditionals[condnum].predecessor == i) {
230 for (k = 0; k < 2; k++) { /* male and female */
231 tilenum++;
232 if (tilenum == file_entry)
233 return conditionals[condnum].name;
237 tilenum++;
239 if (tilenum == file_entry)
240 return "invisible monster";
241 } /* MON_GLYPH */
243 if (set == OBJ_GLYPH) {
244 tilenum = 0; /* set-relative number */
245 for (i = 0; i < NUM_OBJECTS; i++) {
246 /* prefer to give the description - that's all the tile's
247 * appearance should reveal */
248 if (tilenum == file_entry) {
249 if (!obj_descr[i].oc_descr)
250 return obj_descr[i].oc_name;
251 if (!obj_descr[i].oc_name)
252 return obj_descr[i].oc_descr;
254 Sprintf(buf, "%s / %s", obj_descr[i].oc_descr,
255 obj_descr[i].oc_name);
256 return buf;
258 for (condnum = 0; conditionals[condnum].sequence != -1;
259 ++condnum) {
260 if (conditionals[condnum].sequence == OBJ_GLYPH
261 && conditionals[condnum].predecessor == i) {
262 tilenum++;
263 if (tilenum == file_entry)
264 return conditionals[condnum].name;
267 tilenum++;
269 } /* OBJ_GLYPH */
271 if (set == OTH_GLYPH) {
272 tilenum = 0; /* set-relative number */
274 /* S_stone */
275 for (cmap = S_stone; cmap <= S_stone; cmap++) {
276 if (tilenum == file_entry) {
277 if (*defsyms[cmap].explanation) {
278 return defsyms[cmap].explanation;
279 } else if (altlabels[cmap].tilelabel
280 && *altlabels[cmap].tilelabel) {
281 Sprintf(buf, "%s", altlabels[cmap].tilelabel);
282 return buf;
283 } else {
284 Sprintf(buf, "cmap %d %d", cmap, tilenum);
285 return buf;
288 for (condnum = 0; conditionals[condnum].sequence != -1;
289 condnum++) {
290 if (conditionals[condnum].sequence == OTH_GLYPH
291 && conditionals[condnum].predecessor == cmap) {
292 tilenum++;
295 tilenum++;
298 /* walls - level specific */
299 for (k = main_walls; k < mines_walls; k++) {
300 for (cmap = S_vwall; cmap <= S_trwall; cmap++) {
301 i = cmap - S_vwall;
302 if (tilenum == file_entry) {
303 Sprintf(buf, "%s %s", wall_texts[k], walldesc[i]);
304 return buf;
306 for (condnum = 0; conditionals[condnum].sequence != -1;
307 condnum++) {
308 if (conditionals[condnum].sequence == OTH_GLYPH
309 && conditionals[condnum].predecessor == cmap) {
310 tilenum++;
313 tilenum++;
317 /* cmap A */
318 for (cmap = S_ndoor; cmap <= S_brdnladder; cmap++) {
319 i = cmap - S_ndoor; nhUse(i);
320 if (tilenum == file_entry) {
321 if (*defsyms[cmap].explanation) {
322 return defsyms[cmap].explanation;
323 } else if (altlabels[cmap].tilelabel
324 && *altlabels[cmap].tilelabel) {
325 Sprintf(buf, "%s", altlabels[cmap].tilelabel);
326 return buf;
327 } else {
328 Sprintf(buf, "cmap %d %d", cmap, tilenum);
329 return buf;
332 for (condnum = 0; conditionals[condnum].sequence != -1;
333 ++condnum) {
334 if (conditionals[condnum].sequence == OTH_GLYPH
335 && conditionals[condnum].predecessor == cmap) {
336 tilenum++;
337 if (tilenum == file_entry)
338 return conditionals[condnum].name;
341 tilenum++;
344 /* Altars */
345 cmap = S_altar;
346 for (k = altar_unaligned; k <= altar_other; k++) {
347 /* Since defsyms only has one altar symbol,
348 it isn't much help in identifying details
349 these. Roll our own name. */
350 if (tilenum == file_entry) {
351 Sprintf(buf, "%s altar", altar_text[k]);
352 return buf;
354 tilenum++;
356 for (condnum = 0; conditionals[condnum].sequence != -1; ++condnum) {
357 if (conditionals[condnum].sequence == OTH_GLYPH
358 && conditionals[condnum].predecessor == cmap) {
359 tilenum++;
360 if (tilenum == file_entry)
361 return conditionals[condnum].name;
365 /* cmap B */
366 for (cmap = S_grave; cmap < S_arrow_trap + MAXTCHARS; cmap++) {
367 i = cmap - S_grave; nhUse(i);
368 if (tilenum == file_entry) {
369 if (*defsyms[cmap].explanation) {
370 return defsyms[cmap].explanation;
371 } else if (altlabels[cmap].tilelabel
372 && *altlabels[cmap].tilelabel) {
373 Sprintf(buf, "%s", altlabels[cmap].tilelabel);
374 return buf;
375 } else {
376 Sprintf(buf, "cmap %d %d", cmap, tilenum);
377 return buf;
381 for (condnum = 0; conditionals[condnum].sequence != -1;
382 ++condnum) {
383 if (conditionals[condnum].sequence == OTH_GLYPH
384 && conditionals[condnum].predecessor == cmap) {
385 tilenum++;
386 if (tilenum == file_entry)
387 return conditionals[condnum].name;
390 tilenum++;
393 #if 0
394 /* zaps */
395 for (k = 0; k < NUM_ZAP; k++) {
396 offset = GLYPH_ZAP_OFF + (k * ((S_rslant - S_vbeam) + 1));
397 for (cmap = S_vbeam; cmap <= S_rslant; cmap++) {
398 i = cmap - S_vbeam;
399 if (tilenum == file_entry) {
400 Sprintf(buf, "%s zap %d %d", zap_texts[k], k + 1, i % 4);
401 return buf;
403 for (condnum = 0; conditionals[condnum].sequence != -1;
404 condnum++) {
405 if (conditionals[condnum].sequence == OTH_GLYPH
406 && conditionals[condnum].predecessor == cmap) {
407 tilenum++;
410 tilenum++;
413 #else
414 i = file_entry - tilenum;
415 if (i < (NUM_ZAP << 2)) {
416 Sprintf(buf, "%s zap %d %d", zap_texts[i / 4], (i / 4) + 1, i % 4);
417 return buf;
419 tilenum += (NUM_ZAP << 2);
420 #endif
422 /* cmap C */
423 for (cmap = S_digbeam; cmap <= S_goodpos; cmap++) {
424 i = cmap - S_digbeam; nhUse(i);
425 if (tilenum == file_entry) {
426 if (*defsyms[cmap].explanation) {
427 return defsyms[cmap].explanation;
428 } else if (altlabels[cmap].tilelabel
429 && *altlabels[cmap].tilelabel) {
430 Sprintf(buf, "%s", altlabels[cmap].tilelabel);
431 return buf;
432 } else {
433 Sprintf(buf, "cmap %d %d", cmap, tilenum);
434 return buf;
437 for (condnum = 0; conditionals[condnum].sequence != -1;
438 ++condnum) {
439 if (conditionals[condnum].sequence == OTH_GLYPH
440 && conditionals[condnum].predecessor == cmap) {
441 tilenum++;
442 if (tilenum == file_entry)
443 return conditionals[condnum].name;
446 tilenum++;
449 /* swallow */
450 for (cmap = S_sw_tl; cmap <= S_sw_br; cmap++) {
451 i = cmap - S_sw_tl;
452 if (tilenum + i == file_entry) {
453 if (*defsyms[cmap].explanation) {
454 return defsyms[cmap].explanation;
455 } else if (altlabels[cmap].tilelabel
456 && *altlabels[cmap].tilelabel) {
457 Sprintf(buf, "%s", altlabels[cmap].tilelabel);
458 return buf;
459 } else {
460 Sprintf(buf, "cmap swallow %d", cmap);
461 return buf;
465 tilenum += ((S_sw_br - S_sw_tl) + 1);
467 /* explosions */
468 for (k = expl_dark; k <= expl_frosty; k++) {
469 for (cmap = S_expl_tl; cmap <= S_expl_br; cmap++) {
470 i = cmap - S_expl_tl; nhUse(i);
471 if (tilenum == file_entry) {
472 /* substitute "explosion " in the tilelabel
473 with "explosion dark " etc */
474 Sprintf(buf, "explosion %s %s", expl_texts[k],
475 &altlabels[cmap].tilelabel[10]);
476 return buf;
478 for (condnum = 0; conditionals[condnum].sequence != -1;
479 ++condnum) {
480 if (conditionals[condnum].sequence == OTH_GLYPH
481 && conditionals[condnum].predecessor == cmap) {
482 tilenum++;
483 if (tilenum == file_entry)
484 return conditionals[condnum].name;
487 tilenum++;
491 /* warnings */
492 i = file_entry - tilenum;
493 if (i < WARNCOUNT) {
494 Sprintf(buf, "warning %d", i);
495 return buf;
497 tilenum += WARNCOUNT;
499 i = file_entry - tilenum;
500 if (i < 1) {
501 Sprintf(buf, "unexplored");
502 return buf;
504 tilenum += 1;
506 i = file_entry - tilenum;
507 if (i < 1) {
508 Sprintf(buf, "nothing");
509 return buf;
511 tilenum++;
513 /* other level walls */
514 /* this batch starts at mines(1), not main(0) */
515 for (k = mines_walls; k <= sokoban_walls; k++) {
516 for (cmap = S_vwall; cmap <= S_trwall; cmap++) {
517 i = cmap - S_vwall;
518 if (tilenum == file_entry) {
519 Sprintf(buf, "%s %s", wall_texts[k], walldesc[i]);
520 return buf;
522 for (condnum = 0; conditionals[condnum].sequence != -1;
523 condnum++) {
524 if (conditionals[condnum].sequence == OTH_GLYPH
525 && conditionals[condnum].predecessor == cmap) {
526 tilenum++;
529 tilenum++;
532 } /* OTH_GLYPH */
533 Sprintf(buf, "unknown %d %d", set, file_entry);
534 return buf;
536 #endif /* TILETEXT || OBTAIN_TILEMAP */
538 #ifndef TILETEXT
539 #define TILE_FILE "tile.c"
540 #ifdef AMIGA
541 #define SOURCE_TEMPLATE "NH:src/%s"
542 #define INCLUDE_TEMPLATE "NH:include/t.%s"
543 #else
544 #ifdef MAC
545 #define SOURCE_TEMPLATE ":src:%s"
546 #define INCLUDE_TEMPLATE ":include:%s"
547 #else
548 #define SOURCE_TEMPLATE "../src/%s"
549 #define INCLUDE_TEMPLATE "../include/%s"
550 #endif
551 #endif
553 #ifndef STATUES_DONT_LOOK_LIKE_MONSTERS
554 int lastmontile, lastobjtile, lastothtile, laststatuetile;
555 #else
556 int lastmontile, lastobjtile, lastothtile;
557 #endif
559 /* Number of tiles for invisible monsters */
560 #define NUM_INVIS_TILES 1
563 * set up array to map glyph numbers to tile numbers
565 * assumes tiles are numbered sequentially through monsters/objects/other,
566 * with entries for all supported compilation options. monsters have two
567 * tiles for each (male + female).
569 * "other" contains cmap and zaps (the swallow sets are a repeated portion
570 * of cmap), as well as the "flash" glyphs for the new warning system
571 * introduced in 3.3.1.
573 void
574 init_tilemap(void)
576 int i, j, k, cmap, condnum, tilenum, offset;
577 int corpsetile, swallowbase;
578 int file_entry = 0;
580 #if defined(OBTAIN_TILEMAP)
581 tilemap_file = fopen("tilemappings.lst", "w");
582 Fprintf(tilemap_file, "NUMMONS = %d\n", NUMMONS);
583 Fprintf(tilemap_file, "NUM_OBJECTS = %d\n", NUM_OBJECTS);
584 Fprintf(tilemap_file, "MAXEXPCHARS = %d\n", MAXEXPCHARS);
585 Fprintf(tilemap_file, "MAXPCHARS = %d\n", MAXPCHARS);
586 Fprintf(tilemap_file, "MAX_GLYPH = %d\n", MAX_GLYPH);
587 Fprintf(tilemap_file, "GLYPH_MON_OFF = %d\n", GLYPH_MON_OFF);
588 Fprintf(tilemap_file, "GLYPH_MON_MALE_OFF = %d\n", GLYPH_MON_MALE_OFF);
589 Fprintf(tilemap_file, "GLYPH_MON_FEM_OFF = %d\n", GLYPH_MON_FEM_OFF);
590 Fprintf(tilemap_file, "GLYPH_PET_OFF = %d\n", GLYPH_PET_OFF);
591 Fprintf(tilemap_file, "GLYPH_PET_MALE_OFF = %d\n", GLYPH_PET_MALE_OFF);
592 Fprintf(tilemap_file, "GLYPH_PET_FEM_OFF = %d\n", GLYPH_PET_FEM_OFF);
593 Fprintf(tilemap_file, "GLYPH_INVIS_OFF = %d\n", GLYPH_INVIS_OFF);
594 Fprintf(tilemap_file, "GLYPH_DETECT_OFF = %d\n", GLYPH_DETECT_OFF);
595 Fprintf(tilemap_file, "GLYPH_DETECT_MALE_OFF = %d\n",
596 GLYPH_DETECT_MALE_OFF);
597 Fprintf(tilemap_file, "GLYPH_DETECT_FEM_OFF = %d\n",
598 GLYPH_DETECT_FEM_OFF);
599 Fprintf(tilemap_file, "GLYPH_BODY_OFF = %d\n", GLYPH_BODY_OFF);
600 Fprintf(tilemap_file, "GLYPH_RIDDEN_OFF = %d\n", GLYPH_RIDDEN_OFF);
601 Fprintf(tilemap_file, "GLYPH_RIDDEN_MALE_OFF = %d\n",
602 GLYPH_RIDDEN_MALE_OFF);
603 Fprintf(tilemap_file, "GLYPH_RIDDEN_FEM_OFF = %d\n",
604 GLYPH_RIDDEN_FEM_OFF);
605 Fprintf(tilemap_file, "GLYPH_OBJ_OFF = %d\n", GLYPH_OBJ_OFF);
606 Fprintf(tilemap_file, "GLYPH_CMAP_OFF = %d\n", GLYPH_CMAP_OFF);
607 Fprintf(tilemap_file, "GLYPH_CMAP_STONE_OFF = %d\n", GLYPH_CMAP_STONE_OFF);
608 Fprintf(tilemap_file, "GLYPH_CMAP_MAIN_OFF = %d\n", GLYPH_CMAP_MAIN_OFF);
609 Fprintf(tilemap_file, "GLYPH_CMAP_MINES_OFF = %d\n",
610 GLYPH_CMAP_MINES_OFF);
611 Fprintf(tilemap_file, "GLYPH_CMAP_GEH_OFF = %d\n", GLYPH_CMAP_GEH_OFF);
612 Fprintf(tilemap_file, "GLYPH_CMAP_KNOX_OFF = %d\n", GLYPH_CMAP_KNOX_OFF);
613 Fprintf(tilemap_file, "GLYPH_CMAP_SOKO_OFF = %d\n", GLYPH_CMAP_SOKO_OFF);
614 Fprintf(tilemap_file, "GLYPH_CMAP_A_OFF = %d\n", GLYPH_CMAP_A_OFF);
615 Fprintf(tilemap_file, "GLYPH_ALTAR_OFF = %d\n", GLYPH_ALTAR_OFF);
616 Fprintf(tilemap_file, "GLYPH_CMAP_B_OFF = %d\n", GLYPH_CMAP_B_OFF);
617 Fprintf(tilemap_file, "GLYPH_ZAP_OFF = %d\n", GLYPH_ZAP_OFF);
618 Fprintf(tilemap_file, "GLYPH_CMAP_C_OFF = %d\n", GLYPH_CMAP_C_OFF);
619 Fprintf(tilemap_file, "GLYPH_SWALLOW_OFF = %d\n", GLYPH_SWALLOW_OFF);
620 Fprintf(tilemap_file, "GLYPH_EXPLODE_OFF = %d\n", GLYPH_EXPLODE_OFF);
621 Fprintf(tilemap_file, "GLYPH_EXPLODE_DARK_OFF = %d\n",
622 GLYPH_EXPLODE_DARK_OFF);
623 Fprintf(tilemap_file, "GLYPH_EXPLODE_NOXIOUS_OFF = %d\n",
624 GLYPH_EXPLODE_NOXIOUS_OFF);
625 Fprintf(tilemap_file, "GLYPH_EXPLODE_MUDDY_OFF = %d\n",
626 GLYPH_EXPLODE_MUDDY_OFF);
627 Fprintf(tilemap_file, "GLYPH_EXPLODE_WET_OFF = %d\n",
628 GLYPH_EXPLODE_WET_OFF);
629 Fprintf(tilemap_file, "GLYPH_EXPLODE_MAGICAL_OFF = %d\n",
630 GLYPH_EXPLODE_MAGICAL_OFF);
631 Fprintf(tilemap_file, "GLYPH_EXPLODE_FIERY_OFF = %d\n",
632 GLYPH_EXPLODE_FIERY_OFF);
633 Fprintf(tilemap_file, "GLYPH_EXPLODE_FROSTY_OFF = %d\n",
634 GLYPH_EXPLODE_FROSTY_OFF);
635 Fprintf(tilemap_file, "GLYPH_WARNING_OFF = %d\n", GLYPH_WARNING_OFF);
636 Fprintf(tilemap_file, "GLYPH_STATUE_OFF = %d\n", GLYPH_STATUE_OFF);
637 Fprintf(tilemap_file, "GLYPH_STATUE_MALE_OFF = %d\n",
638 GLYPH_STATUE_MALE_OFF);
639 Fprintf(tilemap_file, "GLYPH_STATUE_FEM_OFF = %d\n",
640 GLYPH_STATUE_FEM_OFF);
641 Fprintf(tilemap_file, "GLYPH_OBJ_PILETOP_OFF = %d\n",
642 GLYPH_OBJ_PILETOP_OFF);
643 Fprintf(tilemap_file, "GLYPH_BODY_PILETOP_OFF = %d\n",
644 GLYPH_BODY_PILETOP_OFF);
645 Fprintf(tilemap_file, "GLYPH_STATUE_MALE_PILETOP_OFF = %d\n",
646 GLYPH_STATUE_MALE_PILETOP_OFF);
647 Fprintf(tilemap_file, "GLYPH_STATUE_FEM_PILETOP_OFF = %d\n",
648 GLYPH_STATUE_FEM_PILETOP_OFF);
649 Fprintf(tilemap_file, "GLYPH_UNEXPLORED_OFF = %d\n",
650 GLYPH_UNEXPLORED_OFF);
651 Fprintf(tilemap_file, "GLYPH_NOTHING_OFF = %d\n", GLYPH_NOTHING_OFF);
652 #endif
654 for (i = 0; i < MAX_GLYPH; i++) {
655 tilemap[i].tilenum = -1;
658 corpsetile = NUMMONS /* MON_MALE */
659 + NUMMONS /* MON_FEM */
660 + NUM_INVIS_TILES /* INVIS */
661 + CORPSE; /* within OBJ */
663 swallowbase = NUMMONS /* MON_MALE */
664 + NUMMONS /* MON_FEM */
665 + NUM_INVIS_TILES /* INVIS */
666 + NUM_OBJECTS /* Objects */
667 + 1 /* Stone */
668 + ((S_trwall - S_vwall) + 1) /* main walls */
669 + ((S_brdnladder - S_ndoor) + 1) /* cmap A */
670 + (4 + 1) /* 5 altar tiles */
671 + (S_arrow_trap + MAXTCHARS - S_grave) /* cmap B */
672 + (NUM_ZAP << 2) /* zaps */
673 + ((S_goodpos - S_digbeam) + 1); /* cmap C */
675 /* add number compiled out */
676 for (i = 0; conditionals[i].sequence != TERMINATOR; i++) {
677 switch (conditionals[i].sequence) {
678 case MON_GLYPH:
679 corpsetile += 2;
680 swallowbase += 2;
681 break;
682 case OBJ_GLYPH:
683 if (conditionals[i].predecessor < CORPSE)
684 corpsetile++;
685 swallowbase++;
686 break;
687 case OTH_GLYPH:
688 if (conditionals[i].predecessor < S_sw_tl)
689 swallowbase++;
690 break;
694 tilenum = 0;
695 for (i = 0; i < NUMMONS; i++) {
696 #if defined(OBTAIN_TILEMAP)
697 char buf[256];
698 #endif
700 tilemap[GLYPH_MON_MALE_OFF + i].tilenum = tilenum;
701 tilemap[GLYPH_PET_MALE_OFF + i].tilenum = tilenum;
702 tilemap[GLYPH_DETECT_MALE_OFF + i].tilenum = tilenum;
703 tilemap[GLYPH_RIDDEN_MALE_OFF + i].tilenum = tilenum;
704 tilemap[GLYPH_BODY_OFF + i].tilenum = corpsetile;
705 tilemap[GLYPH_BODY_PILETOP_OFF + i].tilenum = corpsetile;
706 #if defined(OBTAIN_TILEMAP)
707 Sprintf(buf, "%s (mnum=%d)", tilename(MON_GLYPH, file_entry, 0), i);
708 Snprintf(tilemap[GLYPH_MON_MALE_OFF + i].name,
709 sizeof tilemap[0].name,"male %s", buf);
710 Snprintf(tilemap[GLYPH_PET_MALE_OFF + i].name,
711 sizeof tilemap[0].name, "%s male %s", "pet", buf);
712 Snprintf(tilemap[GLYPH_DETECT_MALE_OFF + i].name,
713 sizeof tilemap[0].name, "%s male %s", "detected", buf);
714 Snprintf(tilemap[GLYPH_RIDDEN_MALE_OFF + i].name,
715 sizeof tilemap[0].name, "%s male %s", "ridden", buf);
716 Snprintf(tilemap[GLYPH_BODY_OFF + i].name,
717 sizeof tilemap[0].name, "%s %s", "body of", buf);
718 Snprintf(tilemap[GLYPH_BODY_PILETOP_OFF + i].name,
719 sizeof tilemap[0].name, "%s %s", "piletop body of", buf);
720 add_tileref(tilenum, GLYPH_MON_MALE_OFF + i, monsters_file,
721 file_entry, tilemap[GLYPH_MON_MALE_OFF + i].name, "");
722 add_tileref(tilenum, GLYPH_PET_MALE_OFF + i, monsters_file,
723 file_entry, tilemap[GLYPH_PET_MALE_OFF + i].name, "");
724 add_tileref(tilenum, GLYPH_DETECT_MALE_OFF + i, monsters_file,
725 file_entry, tilemap[GLYPH_DETECT_MALE_OFF + i].name,"");
726 add_tileref(tilenum, GLYPH_RIDDEN_MALE_OFF + i, monsters_file,
727 file_entry, tilemap[GLYPH_RIDDEN_MALE_OFF + i].name, "");
728 add_tileref(corpsetile, GLYPH_BODY_OFF + i, objects_file, CORPSE,
729 tilemap[GLYPH_BODY_OFF + i].name, "");
730 add_tileref(corpsetile, GLYPH_BODY_PILETOP_OFF + i, objects_file,
731 CORPSE, tilemap[GLYPH_BODY_PILETOP_OFF + i].name, "");
732 #endif
733 tilenum++;
734 file_entry++;
735 tilemap[GLYPH_MON_FEM_OFF + i].tilenum = tilenum;
736 tilemap[GLYPH_PET_FEM_OFF + i].tilenum = tilenum;
737 tilemap[GLYPH_DETECT_FEM_OFF + i].tilenum = tilenum;
738 tilemap[GLYPH_RIDDEN_FEM_OFF + i].tilenum = tilenum;
739 #if defined(OBTAIN_TILEMAP)
740 Sprintf(buf, "%s (mnum=%d)", tilename(MON_GLYPH, file_entry, 0), i);
741 Snprintf(tilemap[GLYPH_MON_FEM_OFF + i].name,
742 sizeof tilemap[0].name, "female %s", buf);
743 Snprintf(tilemap[GLYPH_PET_FEM_OFF + i].name,
744 sizeof tilemap[0].name, "%s female %s", "pet",
745 buf);
746 Snprintf(tilemap[GLYPH_DETECT_FEM_OFF + i].name,
747 sizeof tilemap[0].name, "%s female %s",
748 "detected", buf);
749 Snprintf(tilemap[GLYPH_RIDDEN_FEM_OFF + i].name,
750 sizeof tilemap[0].name, "%s female %s",
751 "ridden", buf);
752 Snprintf(tilemap[GLYPH_BODY_OFF + i].name,
753 sizeof tilemap[0].name, "%s %s", "body of", buf);
754 Snprintf(tilemap[GLYPH_BODY_PILETOP_OFF + i].name,
755 sizeof tilemap[0].name, "%s %s",
756 "piletop body of", buf);
757 add_tileref(tilenum, GLYPH_MON_FEM_OFF + i, monsters_file,
758 file_entry, tilemap[GLYPH_MON_FEM_OFF + i].name, "");
759 add_tileref(tilenum, GLYPH_PET_FEM_OFF + i, monsters_file,
760 file_entry, tilemap[GLYPH_PET_FEM_OFF + i].name, "");
761 add_tileref(tilenum, GLYPH_DETECT_FEM_OFF + i, monsters_file,
762 file_entry, tilemap[GLYPH_DETECT_FEM_OFF + i].name, "");
763 add_tileref(tilenum, GLYPH_RIDDEN_FEM_OFF + i, monsters_file,
764 file_entry, tilemap[GLYPH_RIDDEN_FEM_OFF + i].name, "");
765 add_tileref(corpsetile, GLYPH_BODY_OFF + i, objects_file, CORPSE,
766 tilemap[GLYPH_BODY_OFF + i].name, "");
767 add_tileref(corpsetile, GLYPH_BODY_PILETOP_OFF + i, objects_file,
768 corpsetile, tilemap[GLYPH_BODY_PILETOP_OFF + i].name, "");
769 #endif
771 for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) {
772 if (conditionals[condnum].sequence == MON_GLYPH
773 && conditionals[condnum].predecessor == i) {
774 tilenum += 2; /* male and female */
775 file_entry += 2;
776 #if defined(OBTAIN_TILEMAP)
777 Fprintf(tilemap_file, "skipping monst %s (%d)\n",
778 tilename(MON_GLYPH, file_entry, 0), file_entry);
779 #endif
782 tilenum++; /* male + female tiles for each */
783 file_entry++;
785 tilemap[GLYPH_INVISIBLE].tilenum = tilenum;
786 #if defined(OBTAIN_TILEMAP)
787 Sprintf(tilemap[GLYPH_INVISIBLE].name, "%s (mnum=%d)", "invisible mon",
788 file_entry);
789 add_tileref(tilenum, GLYPH_INVISIBLE, monsters_file,
790 file_entry, tilemap[GLYPH_INVISIBLE].name, "invisible ");
791 #endif
792 lastmontile = tilenum;
793 tilenum++;
794 file_entry++; /* non-productive, but in case something ever gets
795 inserted right below here ahead of objects */
797 /* start of objects */
798 file_entry = 0;
799 for (i = 0; i < NUM_OBJECTS; i++) {
800 tilemap[GLYPH_OBJ_OFF + i].tilenum = tilenum;
801 tilemap[GLYPH_OBJ_PILETOP_OFF + i].tilenum = tilenum;
802 #if defined(OBTAIN_TILEMAP)
803 Snprintf(tilemap[GLYPH_OBJ_OFF + i].name,
804 sizeof tilemap[GLYPH_OBJ_OFF + i].name,
805 "%s (onum=%d)",
806 tilename(OBJ_GLYPH, file_entry, 0), i);
807 Snprintf(tilemap[GLYPH_OBJ_PILETOP_OFF + i].name,
808 sizeof tilemap[GLYPH_OBJ_PILETOP_OFF + i].name,
809 "%s %s (onum=%d)",
810 "piletop", tilename(OBJ_GLYPH, file_entry, 0), i);
811 add_tileref(tilenum, GLYPH_OBJ_OFF + i,
812 objects_file, file_entry,
813 tilemap[GLYPH_OBJ_OFF + i].name, "");
814 add_tileref(tilenum, GLYPH_OBJ_PILETOP_OFF + i,
815 objects_file, file_entry,
816 tilemap[GLYPH_OBJ_PILETOP_OFF + i].name, "");
817 #endif
818 for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) {
819 if (conditionals[condnum].sequence == OBJ_GLYPH
820 && conditionals[condnum].predecessor == i) {
821 tilenum++;
822 file_entry++;
823 #if defined(OBTAIN_TILEMAP)
824 Fprintf(tilemap_file, "skipping obj %s (%d)\n",
825 tilename(OBJ_GLYPH, file_entry, 0), file_entry);
826 #endif
829 tilenum++;
830 file_entry++;
832 lastobjtile = tilenum - 1;
834 file_entry = 0;
835 /* S_stone */
836 cmap = S_stone;
837 precheck((GLYPH_CMAP_STONE_OFF), "stone");
838 tilemap[GLYPH_CMAP_STONE_OFF].tilenum = tilenum;
839 #if defined(OBTAIN_TILEMAP)
840 Snprintf(tilemap[GLYPH_CMAP_STONE_OFF].name,
841 sizeof tilemap[0].name,
842 "%s (cmap=%d)",
843 tilename(OTH_GLYPH, file_entry, 0),
844 cmap);
845 add_tileref(tilenum, GLYPH_CMAP_STONE_OFF,
846 other_file, file_entry,
847 tilemap[GLYPH_CMAP_STONE_OFF].name, "");
848 #endif
849 TILE_stone = tilenum; /* Used to init nul_glyphinfo tileidx entry */
850 tilenum++;
851 file_entry++;
853 /* walls in the main dungeon */
854 for (k = main_walls; k < mines_walls; k++) {
855 offset = wall_offsets[k];
856 for (cmap = S_vwall; cmap <= S_trwall; cmap++) {
857 i = cmap - S_vwall;
858 precheck(offset + i, "walls");
859 tilemap[offset + i].tilenum = tilenum;
860 #if defined(OBTAIN_TILEMAP)
861 Snprintf(tilemap[offset + i].name,
862 sizeof tilemap[0].name,
863 "%s (cmap=%d)",
864 tilename(OTH_GLYPH, file_entry, 0),
865 cmap);
866 add_tileref(tilenum, offset + i, other_file, file_entry,
867 tilemap[offset + i].name, "");
868 #endif
869 for (condnum = 0; conditionals[condnum].sequence != -1;
870 condnum++) {
871 if (conditionals[condnum].sequence == OTH_GLYPH
872 && conditionals[condnum].predecessor == cmap) {
873 tilenum++;
874 file_entry++;
875 #if defined(OBTAIN_TILEMAP)
876 Fprintf(tilemap_file, "skipping cmap %s (%d) (%d)\n",
877 tilename(OTH_GLYPH, file_entry, 0), file_entry,
878 cmap);
879 #endif
882 tilenum++;
883 file_entry++;
887 /* cmap A */
888 for (cmap = S_ndoor; cmap <= S_brdnladder; cmap++) {
889 i = cmap - S_ndoor;
890 precheck((GLYPH_CMAP_A_OFF + i), "cmap A");
891 tilemap[GLYPH_CMAP_A_OFF + i].tilenum = tilenum;
892 #if defined(OBTAIN_TILEMAP)
893 Snprintf(tilemap[GLYPH_CMAP_A_OFF + i].name,
894 sizeof tilemap[0].name,
895 "cmap A %s (cmap=%d)",
896 tilename(OTH_GLYPH, file_entry, 0), cmap);
897 add_tileref(tilenum, GLYPH_CMAP_A_OFF + i, other_file, file_entry,
898 tilemap[GLYPH_CMAP_A_OFF + i].name, "");
899 #endif
900 for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) {
901 if (conditionals[condnum].sequence == OTH_GLYPH
902 && conditionals[condnum].predecessor == cmap) {
903 tilenum++;
904 file_entry++;
905 #if defined(OBTAIN_TILEMAP)
906 Fprintf(tilemap_file, "skipping cmap A %s (%d) (%d)\n",
907 tilename(OTH_GLYPH, file_entry, 0), file_entry, cmap);
908 #endif
911 if (cmap == S_corr)
912 TILE_corr = tilenum; /* X11 references this tile during tile init */
913 tilenum++;
914 file_entry++;
917 /* Altars */
918 cmap = S_altar;
919 j = 0;
920 for (k = altar_unaligned; k <= altar_other; k++) {
921 offset = GLYPH_ALTAR_OFF + j;
922 precheck((offset), "altar");
923 tilemap[offset].tilenum = tilenum;
924 #if defined(OBTAIN_TILEMAP)
925 Snprintf(tilemap[offset].name,
926 sizeof tilemap[0].name,
927 "%s %s (cmap=%d)",
928 altar_text[j], tilename(OTH_GLYPH, file_entry, 0), cmap);
929 add_tileref(tilenum, offset, other_file, file_entry,
930 tilemap[offset].name, "");
931 #endif
932 for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) {
933 if (conditionals[condnum].sequence == OTH_GLYPH
934 && conditionals[condnum].predecessor == cmap) {
935 #if defined(OBTAIN_TILEMAP)
936 Fprintf(tilemap_file, "skipping %s %s (%d)\n",
937 altar_text[j],
938 tilename(OTH_GLYPH, file_entry, 0), cmap);
939 #endif
940 tilenum++;
941 file_entry++;
944 j++;
945 tilenum++;
946 file_entry++;
949 /* cmap B */
950 for (cmap = S_grave; cmap < S_arrow_trap + MAXTCHARS; cmap++) {
951 i = cmap - S_grave;
952 precheck((GLYPH_CMAP_B_OFF + i), "cmap B");
953 tilemap[GLYPH_CMAP_B_OFF + i].tilenum = tilenum;
954 #if defined(OBTAIN_TILEMAP)
955 Snprintf(tilemap[GLYPH_CMAP_B_OFF + i].name,
956 sizeof tilemap[0].name,
957 "%s (cmap=%d)",
958 tilename(OTH_GLYPH, file_entry, 0), cmap);
959 add_tileref(tilenum, GLYPH_CMAP_B_OFF + i, other_file, file_entry,
960 tilemap[GLYPH_CMAP_B_OFF + i].name, "");
961 #endif
962 for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) {
963 if (conditionals[condnum].sequence == OTH_GLYPH
964 && conditionals[condnum].predecessor == cmap) {
965 tilenum++;
966 file_entry++;
967 #if defined(OBTAIN_TILEMAP)
968 Fprintf(tilemap_file, "skipping cmap %s (%d) (%d)\n",
969 tilename(OTH_GLYPH, file_entry, 0), file_entry, cmap);
970 #endif
973 tilenum++;
974 file_entry++;
977 /* zaps */
978 #if 0
979 for (k = 0; k < NUM_ZAP; k++) {
980 offset = GLYPH_ZAP_OFF + (k * ((S_rslant - S_vbeam) + 1));
981 for (cmap = S_vbeam; cmap <= S_rslant; cmap++) {
982 i = cmap - S_vbeam;
983 precheck((offset + i), "zaps");
984 tilemap[offset + i].tilenum = tilenum;
985 #if defined(OBTAIN_TILEMAP)
986 Snprintf(tilemap[offset + i].name,
987 sizeof tilemap[0].name,
988 "%s (%d) (%d)",
989 tilename(OTH_GLYPH, file_entry, 0), file_entry, cmap);
990 add_tileref(tilenum, offset + i, other_file, file_entry,
991 tilemap[offset + i].name, "");
992 #endif
993 for (condnum = 0; conditionals[condnum].sequence != -1;
994 condnum++) {
995 if (conditionals[condnum].sequence == OTH_GLYPH
996 && conditionals[condnum].predecessor == cmap) {
997 #if defined(OBTAIN_TILEMAP)
998 Fprintf(tilemap_file, "skipping zap %s (%d) (%d)\n",
999 tilename(OTH_GLYPH, file_entry, 0), file_entry,
1000 cmap);
1001 #endif
1002 file_entry++;
1003 tilenum++;
1007 tilenum++;
1008 file_entry++;
1011 #else
1012 for (i = 0; i < NUM_ZAP << 2; i++) {
1013 tilemap[GLYPH_ZAP_OFF + i].tilenum = tilenum;
1014 #if defined(OBTAIN_TILEMAP)
1015 Snprintf(tilemap[GLYPH_ZAP_OFF + i].name,
1016 sizeof tilemap[0].name,
1017 "zap %s (cmap=%d)",
1018 tilename(OTH_GLYPH, file_entry, 0), (i >> 2));
1019 add_tileref(tilenum, GLYPH_ZAP_OFF + i, other_file, file_entry,
1020 tilemap[GLYPH_ZAP_OFF + i].name, "");
1021 #endif
1022 tilenum++;
1023 file_entry++;
1024 for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) {
1025 if (conditionals[condnum].sequence == OTH_GLYPH
1026 && conditionals[condnum].predecessor == (i + MAXEXPCHARS)) {
1027 #if defined(OBTAIN_TILEMAP)
1028 Fprintf(tilemap_file, "skipping zap %s (%d)\n",
1029 tilename(OTH_GLYPH, file_entry, 0), file_entry);
1030 #endif
1031 file_entry++;
1032 tilenum++;
1036 #endif
1038 /* cmap C */
1039 for (cmap = S_digbeam; cmap <= S_goodpos; cmap++) {
1040 i = cmap - S_digbeam;
1041 precheck((GLYPH_CMAP_C_OFF + i), "cmap C");
1042 tilemap[GLYPH_CMAP_C_OFF + i].tilenum = tilenum;
1043 #if defined(OBTAIN_TILEMAP)
1044 Snprintf(tilemap[GLYPH_CMAP_C_OFF + i].name,
1045 sizeof tilemap[0].name,
1046 "%s (cmap=%d)",
1047 tilename(OTH_GLYPH, file_entry, 0), cmap);
1048 add_tileref(tilenum, GLYPH_CMAP_C_OFF + i, other_file, file_entry,
1049 tilemap[GLYPH_CMAP_C_OFF + i].name, "");
1050 #endif
1051 for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) {
1052 if (conditionals[condnum].sequence == OTH_GLYPH
1053 && conditionals[condnum].predecessor == cmap) {
1054 tilenum++;
1055 file_entry++;
1056 #if defined(OBTAIN_TILEMAP)
1057 Fprintf(tilemap_file, "skipping cmap %s (%d) (%d)\n",
1058 tilename(OTH_GLYPH, file_entry, 0), file_entry, cmap);
1059 #endif
1062 tilenum++;
1063 file_entry++;
1065 /* swallow */
1066 const char *swallow_text[] = {
1067 "swallow top left", "swallow top center",
1068 "swallow top right", "swallow middle left",
1069 "swallow middle right", "swallow bottom left",
1070 "swallow bottom center", "swallow bottom right",
1073 offset = GLYPH_SWALLOW_OFF;
1074 for (k = 0; k < NUMMONS; k++) {
1075 // if (k == 0) {
1076 // swallowbase = tilenum;
1077 // }
1078 for (cmap = S_sw_tl; cmap <= S_sw_br; cmap++) {
1079 i = cmap - S_sw_tl;
1080 precheck((offset + i), "swallows");
1081 tilemap[offset + i].tilenum = swallowbase + i;
1082 #if defined(OBTAIN_TILEMAP)
1083 Snprintf(tilemap[offset + i].name,
1084 sizeof tilemap[0].name,
1085 "%s %s (cmap=%d)",
1086 swallow_text[i],
1087 mons[k].pmnames[NEUTRAL], cmap);
1088 add_tileref(swallowbase + i, offset + i,
1089 other_file, file_entry + i,
1090 tilemap[offset + i].name, "");
1091 #endif
1093 offset += ((S_sw_br - S_sw_tl) + 1);
1095 tilenum += ((S_sw_br - S_sw_tl) + 1);
1096 file_entry += ((S_sw_br - S_sw_tl) + 1);
1098 /* explosions */
1099 for (k = expl_dark; k <= expl_frosty; k++) {
1100 offset = expl_offsets[k];
1101 for (cmap = S_expl_tl; cmap <= S_expl_br; cmap++) {
1102 i = cmap - S_expl_tl;
1103 precheck((offset + i), "explosions");
1104 tilemap[offset + i].tilenum = tilenum;
1105 #if defined(OBTAIN_TILEMAP)
1106 Snprintf(tilemap[offset + i].name,
1107 sizeof tilemap[0].name,
1108 "%s (cmap=%d)",
1109 tilename(OTH_GLYPH, file_entry, 0), cmap);
1110 add_tileref(tilenum, offset + i, other_file, file_entry,
1111 tilemap[offset + i].name, "");
1112 #endif
1114 for (condnum = 0; conditionals[condnum].sequence != -1;
1115 condnum++) {
1116 if (conditionals[condnum].sequence == OTH_GLYPH
1117 && conditionals[condnum].predecessor == cmap) {
1118 #if defined(OBTAIN_TILEMAP)
1119 Fprintf(tilemap_file, "skipping cmap %s (%d)\n",
1120 tilename(OTH_GLYPH, file_entry, 0), cmap);
1121 #endif
1122 tilenum++;
1123 file_entry++;
1126 tilenum++;
1127 file_entry++;
1131 for (i = 0; i < WARNCOUNT; i++) {
1132 precheck((GLYPH_WARNING_OFF + i), "warnings");
1133 tilemap[GLYPH_WARNING_OFF + i].tilenum = tilenum;
1134 #if defined(OBTAIN_TILEMAP)
1135 Snprintf(tilemap[GLYPH_WARNING_OFF + i].name,
1136 sizeof tilemap[0].name,
1137 "%s (warn=%d)",
1138 tilename(OTH_GLYPH, file_entry, 0), file_entry);
1139 add_tileref(tilenum, GLYPH_WARNING_OFF + i, other_file, file_entry,
1140 tilemap[GLYPH_WARNING_OFF + i].name, "");
1141 #endif
1142 tilenum++;
1143 file_entry++;
1146 for (i = 0; i < 1; i++) {
1147 precheck((GLYPH_UNEXPLORED_OFF + i), "unexplored");
1148 tilemap[GLYPH_UNEXPLORED_OFF + i].tilenum = tilenum;
1149 #if defined(OBTAIN_TILEMAP)
1150 Snprintf(tilemap[GLYPH_UNEXPLORED_OFF + i].name,
1151 sizeof tilemap[0].name,
1152 "unexplored %s (%d)",
1153 tilemap[GLYPH_UNEXPLORED_OFF + i].name, file_entry);
1154 add_tileref(tilenum, GLYPH_UNEXPLORED_OFF + i, other_file, file_entry,
1155 tilemap[GLYPH_UNEXPLORED_OFF + i].name, "");
1156 #endif
1157 TILE_unexplored = tilenum; /* for writing into tiledef.h */
1158 tilenum++;
1159 file_entry++;
1162 for (i = 0; i < 1; i++) {
1163 precheck(GLYPH_NOTHING + i, "nothing");
1164 tilemap[GLYPH_NOTHING + i].tilenum = tilenum;
1165 #if defined(OBTAIN_TILEMAP)
1166 Snprintf(tilemap[GLYPH_NOTHING + i].name,
1167 sizeof tilemap[0].name,
1168 " nothing %s (%d)",
1169 tilename(OTH_GLYPH, file_entry, 0), file_entry);
1170 add_tileref(tilenum, GLYPH_NOTHING + i, other_file, file_entry,
1171 tilemap[GLYPH_NOTHING + i].name, "");
1172 #endif
1173 TILE_nothing = tilenum; /* for writing into tiledef.h */
1174 tilenum++;
1175 file_entry++;
1177 /* other walls beyond the main walls */
1178 for (k = mines_walls; k <= sokoban_walls; k++) {
1179 offset = wall_offsets[k];
1180 for (cmap = S_vwall; cmap <= S_trwall; cmap++) {
1181 i = cmap - S_vwall;
1182 precheck(offset + i, "walls");
1183 tilemap[offset + i].tilenum = tilenum;
1184 #if defined(OBTAIN_TILEMAP)
1185 Snprintf(tilemap[offset + i].name,
1186 sizeof tilemap[0].name,
1187 "%s (cmap=%d)",
1188 tilename(OTH_GLYPH, file_entry, 0),
1189 cmap);
1190 add_tileref(tilenum, offset + i, other_file, file_entry,
1191 tilemap[offset + i].name, "");
1192 #endif
1193 for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) {
1194 if (conditionals[condnum].sequence == OTH_GLYPH
1195 && conditionals[condnum].predecessor == cmap) {
1196 tilenum++;
1197 file_entry++;
1198 #if defined(OBTAIN_TILEMAP)
1199 Fprintf(tilemap_file, "skipping cmap %s (%d) (%d)\n",
1200 tilename(OTH_GLYPH, file_entry, 0), file_entry, cmap);
1201 #endif
1204 tilenum++;
1205 file_entry++;
1209 #ifdef STATUES_DONT_LOOK_LIKE_MONSTERS
1210 /* statue patch: statues still use the same glyph as in 3.4.x */
1212 for (i = 0; i < NUMMONS; i++) {
1213 tilemap[GLYPH_STATUE_OFF + i].tilenum =
1214 tilemap[GLYPH_OBJ_OFF + STATUE].tilenum;
1215 #ifdef OBTAIN_TILEMAP
1216 Snprintf(tilemap[GLYPH_STATUE_OFF + i].name,
1217 sizeof tilemap[0].name,
1218 "%s (%d)",
1219 tilename(OTH_GLYPH, file_entry, 0), file_entry);
1220 #endif
1222 #endif
1223 lastothtile = tilenum - 1;
1225 #ifndef STATUES_DONT_LOOK_LIKE_MONSTERS
1226 /* STATUES _DO_ LOOK LIKE MONSTERS */
1227 file_entry = 0;
1228 /* statue patch: statues look more like the monster */
1229 for (i = 0; i < NUMMONS; i++) {
1230 precheck(GLYPH_STATUE_MALE_OFF + i, "male statues");
1231 tilemap[GLYPH_STATUE_MALE_OFF + i].tilenum = tilenum;
1232 precheck(GLYPH_STATUE_MALE_PILETOP_OFF + i, "male statue piletop");
1233 tilemap[GLYPH_STATUE_MALE_PILETOP_OFF + i].tilenum = tilenum;
1234 #if defined(OBTAIN_TILEMAP)
1235 Snprintf(tilemap[GLYPH_STATUE_MALE_OFF + i].name,
1236 sizeof tilemap[0].name,
1237 "statue of male %s (mnum=%d)",
1238 tilename(MON_GLYPH, file_entry, 0), file_entry);
1239 Snprintf(tilemap[GLYPH_STATUE_MALE_PILETOP_OFF + i].name,
1240 sizeof tilemap[0].name,
1241 "piletop statue of male %s (mnum=%d)",
1242 tilename(MON_GLYPH, file_entry, 0), file_entry);
1243 add_tileref(tilenum, GLYPH_STATUE_MALE_OFF + i, generated, file_entry,
1244 tilemap[GLYPH_STATUE_MALE_OFF + i].name,
1245 "");
1246 add_tileref(tilenum, GLYPH_STATUE_MALE_PILETOP_OFF + i, generated,
1247 file_entry,
1248 tilemap[GLYPH_STATUE_MALE_PILETOP_OFF + i].name,
1249 "");
1250 #endif
1251 tilenum++;
1252 file_entry++;
1253 precheck(GLYPH_STATUE_FEM_OFF + i, "female statues");
1254 tilemap[GLYPH_STATUE_FEM_OFF + i].tilenum = tilenum;
1255 precheck(GLYPH_STATUE_FEM_PILETOP_OFF + i, "female statue piletop");
1256 tilemap[GLYPH_STATUE_FEM_PILETOP_OFF + i].tilenum = tilenum;
1257 #if defined(OBTAIN_TILEMAP)
1258 Snprintf(tilemap[GLYPH_STATUE_FEM_OFF + i].name,
1259 sizeof tilemap[0].name,
1260 "statue of female %s (mnum=%d)",
1261 tilename(MON_GLYPH, file_entry, 0), file_entry);
1262 Sprintf(tilemap[GLYPH_STATUE_FEM_PILETOP_OFF + i].name,
1263 "piletop statue of female %s (mnum=%d)",
1264 tilename(MON_GLYPH, file_entry, 0), file_entry);
1265 add_tileref(tilenum, GLYPH_STATUE_FEM_OFF + i, generated, file_entry,
1266 tilemap[GLYPH_STATUE_FEM_OFF + i].name, "");
1267 add_tileref(tilenum, GLYPH_STATUE_FEM_PILETOP_OFF + i, generated,
1268 file_entry,
1269 tilemap[GLYPH_STATUE_FEM_PILETOP_OFF + i].name, "");
1270 #endif
1271 for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) {
1272 if (conditionals[condnum].sequence == MON_GLYPH
1273 && conditionals[condnum].predecessor == i) {
1274 file_entry += 2; /* skip female tile too */
1275 tilenum += 2;
1276 #if defined(OBTAIN_TILEMAP)
1277 Fprintf(tilemap_file, "skipping statue of %s (%d)\n",
1278 tilename(MON_GLYPH, file_entry, 0), file_entry);
1279 #endif
1282 tilenum++;
1283 file_entry++;
1285 /* go beyond NUMMONS to cover off the invisible tile at the
1286 end of monsters.txt so that the tile mapping matches things
1287 in the .bmp file (for example) */
1288 file_entry = 0;
1289 #if defined(OBTAIN_TILEMAP)
1290 add_tileref(tilenum, NO_GLYPH, monsters_file, file_entry,
1291 "invisible statue", "");
1292 #endif
1293 laststatuetile = tilenum - 1;
1294 #endif /* STATUES_DONT_LOOK_LIKE_MONSTERS */
1296 #if defined(OBTAIN_TILEMAP)
1297 for (i = 0; i < MAX_GLYPH; ++i) {
1298 Fprintf(tilemap_file, "glyph[%04d] [%04d] %-80s\n",
1299 i, tilemap[i].tilenum, tilemap[i].name);
1301 dump_tilerefs(tilemap_file);
1302 fclose(tilemap_file);
1303 #endif
1306 #if defined(OBTAIN_TILEMAP)
1307 extern void monst_globals_init(void);
1308 extern void objects_globals_init(void);
1309 #endif
1311 DISABLE_WARNING_UNREACHABLE_CODE
1314 main(int argc UNUSED, char *argv[] UNUSED)
1316 int i, tilenum;
1317 char filename[30];
1318 FILE *ofp;
1319 const char *enhanced;
1320 const char indent[] = " ";
1322 #if defined(OBTAIN_TILEMAP)
1323 objects_globals_init();
1324 monst_globals_init();
1325 #endif
1327 init_tilemap();
1329 #ifdef ENHANCED_SYMBOLS
1330 enhanced = ", utf8rep";
1331 #else
1332 enhanced = "";
1333 #endif
1335 * create the source file, "tile.c"
1337 Snprintf(filename, sizeof filename, SOURCE_TEMPLATE, TILE_FILE);
1338 if (!(ofp = fopen(filename, "w"))) {
1339 perror(filename);
1340 exit(EXIT_FAILURE);
1342 Fprintf(ofp,
1343 "/* This file is automatically generated. Do not edit. */\n");
1344 Fprintf(ofp, "\n#include \"hack.h\"\n");
1345 Fprintf(ofp, "\n#ifndef TILES_IN_GLYPHMAP\n");
1346 Fprintf(ofp, "\n#else /* ?TILES_IN_GLYPHMAP */\n");
1347 Fprintf(ofp, "\nenum special_tiles {\n");
1348 Fprintf(ofp, " TILE_CORR = %d,\n", TILE_corr);
1349 Fprintf(ofp, " TILE_STONE = %d,\n", TILE_stone);
1350 Fprintf(ofp, " TILE_UNEXPLORED = %d\n", TILE_unexplored);
1351 Fprintf(ofp, "};\n");
1352 Fprintf(ofp, "\nint total_tiles_used = %d,\n", laststatuetile + 1);
1353 Fprintf(ofp, "%sTile_corr = TILE_CORR,\n", indent); /* X11 uses it */
1354 Fprintf(ofp, "%sTile_stone = TILE_STONE,\n", indent);
1355 Fprintf(ofp, "%sTile_unexplored = TILE_UNEXPLORED,\n", indent);
1356 Fprintf(ofp, "%smaxmontile = %d,\n", indent, lastmontile);
1357 Fprintf(ofp, "%smaxobjtile = %d,\n", indent, lastobjtile);
1358 Fprintf(ofp, "%smaxothtile = %d;\n\n", indent, lastothtile);
1359 Fprintf(ofp, "#define NO_CUSTOMCOLOR (0U)\n\n");
1360 Fprintf(ofp, "/* glyph, ttychar, { %s%s } */\n",
1361 "glyphflags, { NO_COLOR, symidx }, NO_CUSTOMCOLOR, NO_CUSTOMCOLOR, ovidx, tileidx", enhanced);
1362 #ifdef ENHANCED_SYMBOLS
1363 enhanced = ", 0"; /* replace ", utf8rep" since we're done with that */
1364 #endif
1365 Fprintf(ofp, "const glyph_info nul_glyphinfo = {\n");
1366 Fprintf(ofp, "%sNO_GLYPH, ' ', NO_COLOR,\n", indent);
1367 Fprintf(ofp, "%s%s/* glyph_map */\n", indent, indent);
1368 Fprintf(ofp, "%s%s{ %s, TILE_UNEXPLORED%s }\n", indent, indent,
1369 "MG_UNEXPL, { NO_COLOR, SYM_UNEXPLORED + SYM_OFF_X }, NO_CUSTOMCOLOR, NO_CUSTOMCOLOR",
1370 enhanced);
1371 Fprintf(ofp, "};\n");
1372 Fprintf(ofp, "\nglyph_map glyphmap[MAX_GLYPH] = {\n");
1374 for (i = 0; i < MAX_GLYPH; i++) {
1375 tilenum = tilemap[i].tilenum;
1376 if (tilenum < 0) { /* will be -1 if not assigned a real value */
1377 Fprintf(stderr, "ERROR: glyph %d maps to tile %d.\n", i, tilenum);
1378 (void) fclose(ofp);
1379 unlink(filename);
1380 exit(EXIT_FAILURE);
1381 /*NOTREACHED*/
1383 Fprintf(ofp,
1384 " { 0U, { NO_COLOR, 0 }, NO_CUSTOMCOLOR, NO_CUSTOMCOLOR, %4d%s }, /* [%04d] %s:%03d %s */\n",
1385 tilenum, enhanced, i,
1386 tilesrc_texts[tilelist[tilenum]->src],
1387 tilelist[tilenum]->file_entry,
1388 tilemap[i].name);
1390 Fprintf(ofp, "};\n");
1391 Fprintf(ofp, "\n#endif /* TILES_IN_GLYPHMAP */\n");
1392 Fprintf(ofp, "\n/*tile.c*/\n");
1394 (void) fclose(ofp);
1395 free_tilerefs();
1396 exit(EXIT_SUCCESS);
1397 /*NOTREACHED*/
1398 return 0;
1401 RESTORE_WARNINGS
1403 #endif /* TILETEXT */
1405 boolean
1406 acceptable_tilename(
1407 int glyph_set,
1408 int idx,
1409 const char *encountered,
1410 const char *expected)
1412 int i;
1413 size_t a, b;
1414 char buf[BUFSZ];
1415 const char *pastprefix = encountered;
1416 struct aliaslist {
1417 const char *original;
1418 const char *alias;
1420 struct aliaslist aliases[] = {
1421 { "wall", "vertical wall" },
1422 { "wall", "horizontal wall" },
1423 { "wall", "top left corner wall" },
1424 { "wall", "top right corner wall" },
1425 { "wall", "bottom left corner wall" },
1426 { "wall", "bottom right corner wall" },
1427 { "open door", "vertical open door" },
1428 { "open door", "horizontal open door" },
1429 { "open door", "no door" },
1430 { "altar", "chaotic altar" },
1431 { "altar", "neutral altar" },
1432 { "altar", "lawful altar" },
1433 { "opulent throne", "throne" },
1434 { "water", "pool" },
1435 { "lowered drawbridge", "vertical open drawbridge" },
1436 { "lowered drawbridge", "horizontal open drawbridge" },
1437 { "raised drawbridge", "vertical closed drawbridge" },
1438 { "raised drawbridge", "horizontal closed drawbridge" },
1439 { "altar", "unaligned altar" },
1440 { "altar", "other altar" },
1441 #if 0
1442 { "dark part of a room", "stone" },
1443 #endif
1446 if (glyph_set == OTH_GLYPH) {
1447 if (idx >= 0 && idx < (SIZE(altlabels) - 1)) {
1448 if (!strcmp(altlabels[idx].tilelabel, encountered))
1449 return TRUE;
1451 a = strlen(encountered);
1452 for (i = 0; i < SIZE(aliases); i++) {
1453 if (!strcmp(pastprefix, aliases[i].alias))
1454 return TRUE;
1455 pastprefix = encountered;
1456 b = strlen(aliases[i].alias);
1457 if (a > b) {
1458 pastprefix = encountered + (a - b);
1459 if (!strcmp(pastprefix, aliases[i].alias))
1460 return TRUE;
1462 if (!strcmp(encountered, aliases[i].alias)
1463 && !strcmp(expected, aliases[i].original)) {
1464 return TRUE;
1467 Snprintf(buf, sizeof buf, "cmap tile %d", idx);
1468 if (!strcmp(expected, buf))
1469 return TRUE;
1470 return FALSE;
1472 return TRUE;
1475 #if defined(OBTAIN_TILEMAP)
1476 void
1477 precheck(int offset, const char *glyphtype)
1479 if (tilemap[offset].tilenum != -1)
1480 Fprintf(stderr, "unexpected re-write of tile mapping [%s]\n",
1481 glyphtype);
1484 void
1485 add_tileref(
1486 int n,
1487 int glyphref,
1488 enum tilesrc src,
1489 int entrynum,
1490 const char *nam,
1491 const char *prefix)
1493 struct tiles_used temp = { 0 };
1494 static const char ellipsis[] UNUSED = "...";
1495 char buf[BUFSZ];
1497 if (!tilelist[n]) {
1498 if ((tilelist[n] = malloc(sizeof temp)) != 0) {
1499 tilelist[n]->tilenum = n;
1500 tilelist[n]->src = src;
1501 tilelist[n]->file_entry = entrynum;
1502 /* leave room for trailing "...nnnn" */
1503 Snprintf(tilelist[n]->tilenam, sizeof tilelist[n]->tilenam - 7,
1504 "%s%s", prefix, nam);
1505 tilelist[n]->references[0] = '\0';
1506 } else {
1507 Fprintf(stderr, "tilemap malloc failure %zu bytes\n",
1508 sizeof temp);
1509 exit(EXIT_FAILURE);
1512 Snprintf(temp.references,
1513 sizeof temp.references - 7, /* room for "...nnnn" */
1514 "%s%s%d", tilelist[n]->references,
1515 (tilelist[n]->references[0] != '\0') ? ", " : "", glyphref);
1516 Snprintf(buf, sizeof buf, "...%4d", glyphref);
1517 Snprintf(tilelist[n]->references, sizeof tilelist[n]->references, "%s%s",
1518 temp.references,
1519 (strlen(temp.references) >= (sizeof temp.references - 7) - 1)
1520 ? buf
1521 : "");
1524 void
1525 dump_tilerefs(FILE * fp)
1527 int i;
1529 Fprintf(fp, "\n");
1530 for (i = 0; i < SIZE(tilelist); i++) {
1531 if (tilelist[i]) {
1532 Fprintf(fp, "tile[%04d] %s[%04d] %-25s: %s\n", i,
1533 tilesrc_texts[tilelist[i]->src],
1534 tilelist[i]->file_entry,
1535 tilelist[i]->tilenam,
1536 tilelist[i]->references);
1541 void
1542 free_tilerefs(void)
1544 int i;
1546 for (i = 0; i < SIZE(tilelist); i++) {
1547 if (tilelist[i])
1548 free((genericptr_t) tilelist[i]), tilelist[i] = 0;
1552 #endif
1554 /*tilemap.c*/