/* * CrossFire, A Multiplayer game * * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team * Copyright (C) 2002 Mark Wedel & Crossfire Development Team * Copyright (C) 1992 Frank Tore Johansen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * The maintainer of this code can be reached at */ #include #include #include "face.h" #include "crc.h" faceidx blank_face, empty_face; facehash_t facehash; std::vector faces; std::vector face32, face64; /** * id is the face to smooth, smooth is the 16x2 face used to smooth id. */ struct smoothing : zero_initialised { uint16 id; uint16 smooth; }; /** * Contains all defined smoothing entries. smooth is an array of nrofsmooth * entries. It is sorted by smooth[].id. */ static struct smoothing *smooth = NULL; int nrofsmooth = 0; /* the only thing this table is used for now is to * translate the colorname in the magicmap field of the * face into a numeric index that is then sent to the * client for magic map commands. The order of this table * must match that of the NDI colors in include/newclient.h. */ static const char *const colorname[] = { "black", /* 0 */ "white", /* 1 */ "blue", /* 2 */ "red", /* 3 */ "orange", /* 4 */ "light_blue", /* 5 */ "dark_orange", /* 6 */ "green", /* 7 */ "light_green", /* 8 */ "grey", /* 9 */ "brown", /* 10 */ "yellow", /* 11 */ "khaki" /* 12 */ }; static int compar_smooth (const struct smoothing *a, const struct smoothing *b) { if (a->id < b->id) return -1; if (b->id < a->id) return 1; return 0; } /* * Returns the matching color in the coloralias if found, * 0 otherwise. Note that 0 will actually be black, so there is no * way the calling function can tell if an error occurred or not */ static uint8 find_color (const char *name) { uint8 i; for (i = 0; i < sizeof (colorname) / sizeof (*colorname); i++) if (!strcmp (name, colorname[i])) return i; LOG (llevError, "Unknown color: %s\n", name); return 0; } int face_find (const char *name, int defidx) { facehash_t::iterator i = facehash.find (name); return i == facehash.end () ? defidx : i->second; } facedata * face_data (int idx, int faceset) { return &(faceset ? face64 : face32)[idx]; } /* Reads the smooth file to know how to smooth datas. * the smooth file if made of 2 elements lines. * lines starting with # are comment * the first element of line is face to smooth * the next element is the 16x2 faces picture * used for smoothing */ int ReadSmooth (void) { char buf[MAX_BUF], *p, *q; FILE *fp; int smoothcount = 0; sprintf (buf, "%s/smooth", settings.datadir); LOG (llevDebug, "Reading smooth from %s...\n", buf); if ((fp = fopen (buf, "r")) == NULL) { LOG (llevError, "Cannot open smooth file %s: %s\n", strerror (errno)); exit (-1); } /* First count how many smooth we have, so we can allocate correctly */ while (fgets (buf, MAX_BUF, fp) != NULL) if (buf[0] != '#' && buf[0] != '\n') smoothcount++; rewind (fp); smooth = new smoothing[smoothcount]; while (nrofsmooth < smoothcount && fgets (buf, MAX_BUF, fp) != NULL) { if (*buf == '#') continue; p = strchr (buf, ' '); if (!p) continue; *p = '\0'; q = buf; smooth[nrofsmooth].id = face_find (q); q = p + 1; smooth[nrofsmooth].smooth = face_find (q); nrofsmooth++; } fclose (fp); LOG (llevDebug, "done (got %d smooth entries)\n", nrofsmooth); qsort (smooth, nrofsmooth, sizeof (struct smoothing), (int (*)(const void *, const void *)) compar_smooth); return nrofsmooth; } /** * Find the smooth face for a given face. * * @param face the face to find the smoothing face for * * @param smoothed return value: set to smooth face * * @return 1=smooth face found, 0=no smooth face found */ int FindSmooth (uint16 face, uint16 * smoothed) { struct smoothing *bp, tmp; tmp.id = face; bp = (struct smoothing *) bsearch (&tmp, smooth, nrofsmooth, sizeof (struct smoothing), (int (*)(const void *, const void *)) compar_smooth); (*smoothed) = 0; if (bp) (*smoothed) = bp->smooth; return bp ? 1 : 0; }