*** empty log message ***
This commit is contained in:
529
win/share/tilemap.c
Normal file
529
win/share/tilemap.c
Normal file
@@ -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 */
|
||||
Reference in New Issue
Block a user