From: jwalz Date: Sat, 5 Jan 2002 21:06:02 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: MOVE2GIT~3569 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a890b719d21266580b23ccd1d4d8ca10bf1e01f8;p=nethack *** empty log message *** --- diff --git a/win/share/tilemap.c b/win/share/tilemap.c new file mode 100644 index 000000000..4d7b851eb --- /dev/null +++ b/win/share/tilemap.c @@ -0,0 +1,529 @@ +/* SCCS Id: @(#)tilemap.c 3.3 2000/06/04 */ +/* NetHack may be freely redistributed. See license for details. */ + +/* + * This source file is compiled twice: + * once without TILETEXT defined to make tilemap.{o,obj}, + * then again with it defined to produce tiletxt.{o,obj}. + */ + +#include "hack.h" + +const char * FDECL(tilename, (int, int)); +void NDECL(init_tilemap); +void FDECL(process_substitutions, (FILE *)); + +#ifdef MICRO +#undef exit +#if !defined(MSDOS) && !defined(WIN32) +extern void FDECL(exit, (int)); +#endif +#endif + +#define MON_GLYPH 1 +#define OBJ_GLYPH 2 +#define OTH_GLYPH 3 /* fortunately unnecessary */ + +/* note that the ifdefs here should be the opposite sense from monst.c/ + * objects.c/rm.h + */ + +struct conditionals { + int sequence, predecessor; + const char *name; +} conditionals[] = { +#ifndef CHARON /* not supported yet */ + { MON_GLYPH, PM_HELL_HOUND, "Cerberus" }, +#endif + /* commented out in monst.c at present */ + { MON_GLYPH, PM_SHOCKING_SPHERE, "beholder" }, + { MON_GLYPH, PM_BABY_SILVER_DRAGON, "baby shimmering dragon" }, + { MON_GLYPH, PM_SILVER_DRAGON, "shimmering dragon" }, + { MON_GLYPH, PM_JABBERWOCK, "vorpal jabberwock" }, +#ifndef KOPS + { MON_GLYPH, PM_JABBERWOCK, "Keystone Kop" }, + { MON_GLYPH, PM_JABBERWOCK, "Kop Sergeant" }, + { MON_GLYPH, PM_JABBERWOCK, "Kop Lieutenant" }, + { MON_GLYPH, PM_JABBERWOCK, "Kop Kaptain" }, +#endif + { MON_GLYPH, PM_VAMPIRE_LORD, "vampire mage" }, +#ifndef CHARON /* not supported yet */ + { MON_GLYPH, PM_CROESUS, "Charon" }, +#endif +#ifndef MAIL + { MON_GLYPH, PM_FAMINE, "mail daemon" }, +#endif +#ifndef TOURIST + { MON_GLYPH, PM_SAMURAI, "tourist" }, +#endif + /* commented out in monst.c at present */ + { MON_GLYPH, PM_SHAMAN_KARNOV, "Earendil" }, + { MON_GLYPH, PM_SHAMAN_KARNOV, "Elwing" }, +#ifndef TOURIST + { MON_GLYPH, PM_LORD_SATO, "Twoflower" }, +#endif + /* commented out in monst.c at present */ + { MON_GLYPH, PM_CHROMATIC_DRAGON, "Goblin King" }, + { MON_GLYPH, PM_NEANDERTHAL, "High-elf" }, +#ifndef TOURIST + { MON_GLYPH, PM_ROSHI, "guide" }, +#endif +#ifndef KOPS + { OBJ_GLYPH, CLUB, "rubber hose" }, +#endif + /* objects commented out in objects.c at present */ + { OBJ_GLYPH, SILVER_DRAGON_SCALE_MAIL, "shimmering dragon scale mail" }, + { OBJ_GLYPH, SILVER_DRAGON_SCALES, "shimmering dragon scales" }, +#ifndef TOURIST + { OBJ_GLYPH, LEATHER_JACKET, "Hawaiian shirt" }, + { OBJ_GLYPH, LEATHER_JACKET, "T-shirt" }, + { OBJ_GLYPH, LOCK_PICK, "credit card" }, + { OBJ_GLYPH, MAGIC_LAMP, "expensive camera" }, +#endif +#ifndef STEED + { OBJ_GLYPH, TOWEL, "saddle" }, +#endif + /* allow slime mold to look like slice of pizza, since we + * don't know what a slime mold should look like when renamed anyway + */ +#ifndef MAIL + { OBJ_GLYPH, SCR_STINKING_CLOUD+4, "stamped / mail" }, +#endif + { 0, 0, 0} +}; + + +/* + * Some entries in glyph2tile[] should be substituted for on various levels. + * The tiles used for the substitute entries will follow the usual ones in + * other.til in the order given here, which should have every substitution + * for the same set of tiles grouped together. You will have to change + * more code in process_substitutions()/substitute_tiles() if the sets + * overlap in the future. + */ +struct substitute { + int first_glyph, last_glyph; + const char *sub_name; /* for explanations */ + const char *level_test; +} substitutes[] = { + { GLYPH_CMAP_OFF + S_vwall, GLYPH_CMAP_OFF + S_trwall, + "mine walls", "In_mines(plev)" }, + { GLYPH_CMAP_OFF + S_vwall, GLYPH_CMAP_OFF + S_trwall, + "gehennom walls", "In_hell(plev)" }, + { GLYPH_CMAP_OFF + S_vwall, GLYPH_CMAP_OFF + S_trwall, + "knox walls", "Is_knox(plev)" }, + { GLYPH_CMAP_OFF + S_vwall, GLYPH_CMAP_OFF + S_trwall, + "sokoban walls", "In_sokoban(plev)" } +}; + + +#ifdef TILETEXT + +/* + * entry is the position of the tile within the monsters/objects/other set + */ +const char * +tilename(set, entry) +int set, entry; +{ + int i, j, condnum, tilenum; + static char buf[BUFSZ]; + + /* Note: these initializers don't do anything except guarantee that + we're linked properly. + */ + monst_init(); + objects_init(); + (void) def_char_to_objclass(']'); + + condnum = tilenum = 0; + + for (i = 0; i < NUMMONS; i++) { + if (set == MON_GLYPH && tilenum == entry) + return mons[i].mname; + tilenum++; + while (conditionals[condnum].sequence == MON_GLYPH && + conditionals[condnum].predecessor == i) { + if (set == MON_GLYPH && tilenum == entry) + return conditionals[condnum].name; + condnum++; + tilenum++; + } + } + if (set == MON_GLYPH && tilenum == entry) + return "invisible monster"; + + tilenum = 0; /* set-relative number */ + for (i = 0; i < NUM_OBJECTS; i++) { + /* prefer to give the description - that's all the tile's + * appearance should reveal */ + if (set == OBJ_GLYPH && tilenum == entry) { + if ( !obj_descr[i].oc_descr ) + return obj_descr[i].oc_name; + if ( !obj_descr[i].oc_name ) + return obj_descr[i].oc_descr; + + Sprintf(buf, "%s / %s", + obj_descr[i].oc_descr, + obj_descr[i].oc_name); + return buf; + } + + tilenum++; + while (conditionals[condnum].sequence == OBJ_GLYPH && + conditionals[condnum].predecessor == i) { + if (set == OBJ_GLYPH && tilenum == entry) + return conditionals[condnum].name; + condnum++; + tilenum++; + } + } + + tilenum = 0; /* set-relative number */ + for (i = 0; i < (MAXPCHARS - MAXEXPCHARS); i++) { + if (set == OTH_GLYPH && tilenum == entry) { + if (*defsyms[i].explanation) + return defsyms[i].explanation; + else { + /* if SINKS are turned off, this + * string won't be there (and can't be there + * to prevent symbol-identification and + * special-level mimic appearances from + * thinking the items exist) + */ + switch (i) { + case S_sink: + Sprintf(buf, "sink"); + break; + default: + Sprintf(buf, "cmap %d", tilenum); + break; + } + return buf; + } + } + tilenum++; + while (conditionals[condnum].sequence == OTH_GLYPH && + conditionals[condnum].predecessor == i) { + if (set == OTH_GLYPH && tilenum == entry) + return conditionals[condnum].name; + condnum++; + tilenum++; + } + } + /* explosions */ + tilenum = MAXPCHARS - MAXEXPCHARS; + i = entry - tilenum; + if (i < (MAXEXPCHARS * EXPL_MAX)) { + if (set == OTH_GLYPH) { + char *explosion_types[] = { /* hack.h */ + "dark", "noxious", "muddy", "wet", + "magical", "fiery", "frosty" + }; + Sprintf(buf, "explosion %s %d", + explosion_types[i / MAXEXPCHARS], i % MAXEXPCHARS); + return buf; + } + } + tilenum += (MAXEXPCHARS * EXPL_MAX); + + i = entry - tilenum; + if (i < (NUM_ZAP << 2)) { + if (set == OTH_GLYPH) { + Sprintf(buf, "zap %d %d", i/4, i%4); + return buf; + } + } + tilenum += (NUM_ZAP << 2); + + i = entry - tilenum; + if (i < WARNCOUNT) { + if (set == OTH_GLYPH) { + Sprintf(buf, "warning %d", i); + return buf; + } + } + tilenum += WARNCOUNT; + + for (i = 0; i < SIZE(substitutes); i++) { + j = entry - tilenum; + if (j <= substitutes[i].last_glyph - substitutes[i].first_glyph) { + if (set == OTH_GLYPH) { + Sprintf(buf, "sub %s %d", substitutes[i].sub_name, j); + return buf; + } + } + tilenum += substitutes[i].last_glyph + - substitutes[i].first_glyph + 1; + } + + Sprintf(buf, "unknown %d %d", set, entry); + return buf; +} + +#else /* TILETEXT */ + +#define TILE_FILE "tile.c" + +#ifdef AMIGA +# define SOURCE_TEMPLATE "NH:src/%s" +#else +# ifdef MAC +# define SOURCE_TEMPLATE ":src:%s" +# else +# define SOURCE_TEMPLATE "../src/%s" +# endif +#endif + +short tilemap[MAX_GLYPH]; +int lastmontile, lastobjtile, lastothtile; + +/* Number of tiles for invisible monsters */ +#define NUM_INVIS_TILES 1 + +/* + * set up array to map glyph numbers to tile numbers + * + * assumes tiles are numbered sequentially through monsters/objects/other, + * with entries for all supported compilation options + * + * "other" contains cmap and zaps (the swallow sets are a repeated portion + * of cmap), as well as the "flash" glyphs for the new warning system + * introduced in 3.3.1. + */ +void +init_tilemap() +{ + int i, j, condnum, tilenum; + int corpsetile, swallowbase; + + for (i = 0; i < MAX_GLYPH; i++) { + tilemap[i] = -1; + } + + corpsetile = NUMMONS + NUM_INVIS_TILES + CORPSE; + swallowbase= NUMMONS + NUM_INVIS_TILES + NUM_OBJECTS + S_sw_tl; + + /* add number compiled out */ + for (i = 0; conditionals[i].sequence; i++) { + switch (conditionals[i].sequence) { + case MON_GLYPH: + corpsetile++; + swallowbase++; + break; + case OBJ_GLYPH: + if (conditionals[i].predecessor < CORPSE) + corpsetile++; + swallowbase++; + break; + case OTH_GLYPH: + if (conditionals[i].predecessor < S_sw_tl) + swallowbase++; + break; + } + } + + condnum = tilenum = 0; + for (i = 0; i < NUMMONS; i++) { + tilemap[GLYPH_MON_OFF+i] = tilenum; + tilemap[GLYPH_PET_OFF+i] = tilenum; + tilemap[GLYPH_DETECT_OFF+i] = tilenum; + tilemap[GLYPH_RIDDEN_OFF+i] = tilenum; + tilemap[GLYPH_BODY_OFF+i] = corpsetile; + j = GLYPH_SWALLOW_OFF + 8*i; + tilemap[j] = swallowbase; + tilemap[j+1] = swallowbase+1; + tilemap[j+2] = swallowbase+2; + tilemap[j+3] = swallowbase+3; + tilemap[j+4] = swallowbase+4; + tilemap[j+5] = swallowbase+5; + tilemap[j+6] = swallowbase+6; + tilemap[j+7] = swallowbase+7; + tilenum++; + while (conditionals[condnum].sequence == MON_GLYPH && + conditionals[condnum].predecessor == i) { + condnum++; + tilenum++; + } + } + tilemap[GLYPH_INVISIBLE] = tilenum++; + lastmontile = tilenum - 1; + + for (i = 0; i < NUM_OBJECTS; i++) { + tilemap[GLYPH_OBJ_OFF+i] = tilenum; + tilenum++; + while (conditionals[condnum].sequence == OBJ_GLYPH && + conditionals[condnum].predecessor == i) { + condnum++; + tilenum++; + } + } + lastobjtile = tilenum - 1; + + for (i = 0; i < (MAXPCHARS - MAXEXPCHARS); i++) { + tilemap[GLYPH_CMAP_OFF+i] = tilenum; + tilenum++; + while (conditionals[condnum].sequence == OTH_GLYPH && + conditionals[condnum].predecessor == i) { + condnum++; + tilenum++; + } + } + + for (i = 0; i < (MAXEXPCHARS * EXPL_MAX); i++) { + tilemap[GLYPH_EXPLODE_OFF+i] = tilenum; + tilenum++; + while (conditionals[condnum].sequence == OTH_GLYPH && + conditionals[condnum].predecessor == (i + MAXPCHARS)) { + condnum++; + tilenum++; + } + } + + for (i = 0; i < NUM_ZAP << 2; i++) { + tilemap[GLYPH_ZAP_OFF+i] = tilenum; + tilenum++; + while (conditionals[condnum].sequence == OTH_GLYPH && + conditionals[condnum].predecessor == (i + MAXEXPCHARS)) { + condnum++; + tilenum++; + } + } + + for (i = 0; i < WARNCOUNT; i++) { + tilemap[GLYPH_WARNING_OFF+i] = tilenum; + tilenum++; + } + + lastothtile = tilenum - 1; +} + +const char *prolog[] = { + "", + "", + "void", + "substitute_tiles(plev)", + "d_level *plev;", + "{", + "\tint i;", + "" +}; + +const char *epilog[] = { + "}" +}; + +/* write out the substitutions in an easily-used form. */ +void +process_substitutions(ofp) +FILE *ofp; +{ + int i, j, k, span, start; + + fprintf(ofp, "\n\n"); + + j = 0; /* unnecessary */ + span = -1; + for (i = 0; i < SIZE(substitutes); i++) { + if (i == 0 + || substitutes[i].first_glyph != substitutes[j].first_glyph + || substitutes[i].last_glyph != substitutes[j].last_glyph) { + j = i; + span++; + fprintf(ofp, "short std_tiles%d[] = { ", span); + for (k = substitutes[i].first_glyph; + k < substitutes[i].last_glyph; k++) + fprintf(ofp, "%d, ", tilemap[k]); + fprintf(ofp, "%d };\n", + tilemap[substitutes[i].last_glyph]); + } + } + + for (i = 0; i < SIZE(prolog); i++) { + fprintf(ofp, "%s\n", prolog[i]); + } + j = -1; + span = -1; + start = lastothtile + 1; + for (i = 0; i < SIZE(substitutes); i++) { + if (i == 0 + || substitutes[i].first_glyph != substitutes[j].first_glyph + || substitutes[i].last_glyph != substitutes[j].last_glyph) { + if (i != 0) { /* finish previous span */ + fprintf(ofp, "\t} else {\n"); + fprintf(ofp, "\t\tfor (i = %d; i <= %d; i++)\n", + substitutes[j].first_glyph, + substitutes[j].last_glyph); + fprintf(ofp, "\t\t\tglyph2tile[i] = std_tiles%d[i - %d];\n", + span, substitutes[j].first_glyph); + fprintf(ofp, "\t}\n\n"); + } + j = i; + span++; + } + if (i != j) fprintf(ofp, "\t} else "); + fprintf(ofp, "\tif (%s) {\n", substitutes[i].level_test); + fprintf(ofp, "\t\tfor (i = %d; i <= %d; i++)\n", + substitutes[i].first_glyph, + substitutes[i].last_glyph); + fprintf(ofp, "\t\t\tglyph2tile[i] = %d + i - %d;\n", + start, substitutes[i].first_glyph); + start += substitutes[i].last_glyph - substitutes[i].first_glyph + 1; + } + /* finish last span */ + fprintf(ofp, "\t} else {\n"); + fprintf(ofp, "\t\tfor (i = %d; i <= %d; i++)\n", + substitutes[j].first_glyph, + substitutes[j].last_glyph); + fprintf(ofp, "\t\t\tglyph2tile[i] = std_tiles%d[i - %d];\n", + span, substitutes[j].first_glyph); + fprintf(ofp, "\t}\n\n"); + + for (i = 0; i < SIZE(epilog); i++) { + fprintf(ofp, "%s\n", epilog[i]); + } + + fprintf(ofp, "\nint total_tiles_used = %d;\n", start); + lastothtile = start - 1; +} + +int main() +{ + register int i; + char filename[30]; + FILE *ofp; + + init_tilemap(); + + /* + * create the source file, "tile.c" + */ + Sprintf(filename, SOURCE_TEMPLATE, TILE_FILE); + if (!(ofp = fopen(filename, "w"))) { + perror(filename); + exit(EXIT_FAILURE); + } + fprintf(ofp,"/* This file is automatically generated. Do not edit. */\n"); + fprintf(ofp,"\n#include \"hack.h\"\n\n"); + fprintf(ofp,"short glyph2tile[MAX_GLYPH] = {\n"); + + for (i = 0; i < MAX_GLYPH; i++) { + fprintf(ofp,"%2d,%c", tilemap[i], (i % 12) ? ' ' : '\n'); + } + fprintf(ofp,"%s};\n", (i % 12) ? "\n" : ""); + + process_substitutions(ofp); + + fprintf(ofp,"\n#define MAXMONTILE %d\n", lastmontile); + fprintf(ofp,"#define MAXOBJTILE %d\n", lastobjtile); + fprintf(ofp,"#define MAXOTHTILE %d\n", lastothtile); + + fprintf(ofp,"\n/*tile.c*/\n"); + + fclose(ofp); + exit(EXIT_SUCCESS); + /*NOTREACHED*/ + return 0; +} + +#endif /* TILETEXT */