--- deliantra/server/common/image.C 2007/03/04 19:36:12 1.18 +++ deliantra/server/common/image.C 2007/03/11 02:12:44 1.19 @@ -26,44 +26,14 @@ #include #include +#include "face.h" #include "crc.h" -facetile *new_faces; +faceidx blank_face, empty_face; -/* bmappair and xbm are used when looking for the image id numbers - * of a face by name. xbm is sorted alphabetically so that bsearch - * can be used to quickly find the entry for a name. the number is - * then an index into the new_faces array. - * This data is redundant with new_face information - the difference - * is that this data gets sorted, and that doesn't necessarily happen - * with the new_face data - when accessing new_face[some number], - * that some number corresponds to the face at that number - for - * xbm, it may not. At current time, these do in fact match because - * the bmaps file is created in a sorted order. - */ - -struct bmappair -{ - char *name; - unsigned int number; -}; - -static struct bmappair *xbm = NULL; - -facetile *blank_face, *dark_faces[3], *empty_face; - -/* nroffiles is the actual number of bitmaps defined. - * nrofpixmaps is the number of bitmaps loaded. With - * the automatic generation of the bmaps file, this is now equal - * to nroffiles. - * - * The xbm array (which contains name and number information, and - * is then sorted) contains nroffiles entries. the xbm_names - * array (which is used for converting the numeric face to - * a name) contains nrofpixmaps entries. - */ -static int nroffiles = 0; -int nrofpixmaps = 0; +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. @@ -104,12 +74,6 @@ }; static int -compar (const struct bmappair *a, const struct bmappair *b) -{ - return strcmp (a->name, b->name); -} - -static int compar_smooth (const struct smoothing *a, const struct smoothing *b) { if (a->id < b->id) @@ -132,231 +96,24 @@ 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; } -/* This reads the lib/faces file, getting color and visibility information. - * it is called by ReadBmapNames. - */ -static void -ReadFaceData (void) +int +face_find (const char *name, int defidx) { - char buf[MAX_BUF], *cp; - facetile *on_face = NULL; - FILE *fp; + facehash_t::iterator i = facehash.find (name); - sprintf (buf, "%s/faces", settings.datadir); - LOG (llevDebug, "Reading faces from %s...\n", buf); - if ((fp = fopen (buf, "r")) == NULL) - { - LOG (llevError, "Cannot open faces file %s: %s\n", buf, strerror (errno)); - exit (-1); - } - while (fgets (buf, MAX_BUF, fp) != NULL) - { - if (*buf == '#') - continue; - if (!strncmp (buf, "end", 3)) - { - on_face = NULL; - } - else if (!strncmp (buf, "face", 4)) - { - int tmp; - - cp = buf + 5; - cp[strlen (cp) - 1] = '\0'; /* remove newline */ - - if ((tmp = FindFace (cp, -1)) == -1) - { - LOG (llevError, "Could not find face %s\n", cp); - continue; - } - on_face = &new_faces[tmp]; - on_face->visibility = 0; - } - else if (on_face == NULL) - { - LOG (llevError, "Got line with no face set: %s\n", buf); - } - else if (!strncmp (buf, "color_fg", 8)) - { - cp = buf + 9; - cp[strlen (cp) - 1] = '\0'; - if (on_face->magicmap == 255) - on_face->magicmap = find_color (cp); - } - else if (!strncmp (buf, "color_bg", 8)) - { - /* ignore it */ - } - else if (!strncmp (buf, "visibility", 10)) - { - on_face->visibility = atoi (buf + 11); - } - else if (!strncmp (buf, "magicmap", 8)) - { - cp = buf + 9; - cp[strlen (cp) - 1] = '\0'; - on_face->magicmap = find_color (cp); - } - else if (!strncmp (buf, "is_floor", 8)) - { - int value = atoi (buf + 9); - - if (value) - on_face->magicmap |= FACE_FLOOR; - } - else - LOG (llevDebug, "Got unknown line in faces file: %s\n", buf); - } - - LOG (llevDebug, "done\n"); - fclose (fp); + return i == facehash.end () + ? defidx : i->second; } -/* This reads the bmaps file to get all the bitmap names and - * stuff. It only needs to be done once, because it is player - * independent (ie, what display the person is on will not make a - * difference.) - */ -void -ReadBmapNames (void) +facedata * +face_data (int idx, int faceset) { - char buf[MAX_BUF], *p, *q; - FILE *fp; - int value, nrofbmaps = 0, i; - size_t l; - crc32 crc; - - sprintf (buf, "%s/bmaps", settings.datadir); - LOG (llevDebug, "Reading bmaps from %s...\n", buf); - if ((fp = fopen (buf, "r")) == NULL) - { - LOG (llevError, "Cannot open bmaps file %s: %s\n", buf, strerror (errno)); - exit (-1); - } - - /* First count how many bitmaps we have, so we can allocate correctly */ - while (fgets (buf, MAX_BUF, fp) != NULL) - if (buf[0] != '#' && buf[0] != '\n') - nrofbmaps++; - rewind (fp); - - xbm = new bmappair[nrofbmaps]; - memset (xbm, 0, sizeof (struct bmappair) * nrofbmaps); - - while (nroffiles < nrofbmaps && fgets (buf, MAX_BUF, fp) != NULL) - { - if (*buf == '#') - continue; - - p = (*buf == '\\') ? (buf + 1) : buf; - if (!(p = strtok (p, " \t")) || !(q = strtok (NULL, " \t\n"))) - { - LOG (llevDebug, "Warning, syntax error: %s\n", buf); - continue; - } - - value = atoi (p); - xbm[nroffiles].name = strdup (q); - - /* We need to calculate the checksum of the bmaps file - * name->number mapping to send to the client. This does not - * need to match what sum or other utility may come up with - - * as long as we get the same results on the same real file - * data, it does the job as it lets the client know if - * the file has the same data or not. - */ - crc (value); - crc (value >> 8); - - for (l = 0; l < strlen (q); l++) - crc (q [l]); - - xbm[nroffiles].number = value; - nroffiles++; - if (value >= nrofpixmaps) - nrofpixmaps = value + 1; - } - - fclose (fp); - - LOG (llevDebug, "done (got %d/%d/%d)\n", nrofpixmaps, nrofbmaps, nroffiles); - - new_faces = new facetile[nrofpixmaps]; - - for (i = 0; i < nrofpixmaps; i++) - { - new_faces[i].name = ""; - new_faces[i].number = i; - new_faces[i].visibility = 0; - new_faces[i].magicmap = 255; - } - - for (i = 0; i < nroffiles; i++) - new_faces[xbm[i].number].name = xbm[i].name; - - // non-pod datatype, likely not allowed - qsort (xbm, nroffiles, sizeof (struct bmappair), (int (*)(const void *, const void *)) compar); - - ReadFaceData (); - - for (i = 0; i < nrofpixmaps; i++) - { - if (new_faces[i].magicmap == 255) - { -#if 0 /* Useful for initial debugging, not needed now */ - LOG (llevDebug, "Face %s still had default magicmap, resetting to black\n", new_faces[i].name); -#endif - new_faces[i].magicmap = 0; - } - } - /* Actually forcefully setting the colors here probably should not - * be done - it could easily create confusion. - */ - blank_face = &new_faces[FindFace (BLANK_FACE_NAME, 0)]; - blank_face->magicmap = find_color ("khaki") | FACE_FLOOR; - - empty_face = &new_faces[FindFace (EMPTY_FACE_NAME, 0)]; - - dark_faces[0] = &new_faces[FindFace (DARK_FACE1_NAME, 0)]; - dark_faces[1] = &new_faces[FindFace (DARK_FACE2_NAME, 0)]; - dark_faces[2] = &new_faces[FindFace (DARK_FACE3_NAME, 0)]; - - bmaps_checksum = crc; -} - -/* This returns an the face number of face 'name'. Number is constant - * during an invocation, but not necessarily between versions (this - * is because the faces are arranged in alphabetical order, so - * if a face is removed or added, all faces after that will now - * have a different number. - * - * the parameter error determines behaviour. If a face is - * not found, then error is returned. This can be useful if - * you want some default face used, or can be set to negative - * so that it will be known that the face could not be found - * (needed in client, so that it will know to request that image - * from the server) - */ -int -FindFace (const char *name, int error) -{ - struct bmappair *bp, tmp; - char *p; - - if (!name) - return error; - - if ((p = strchr (name, '\n'))) - *p = '\0'; - - tmp.name = (char *) name; - bp = (struct bmappair *) bsearch (&tmp, xbm, nroffiles, sizeof (struct bmappair), (int (*)(const void *, const void *)) compar); - - return bp ? bp->number : error; + return &(faceset ? face64 : face32)[idx]; } /* Reads the smooth file to know how to smooth datas. @@ -398,9 +155,9 @@ continue; *p = '\0'; q = buf; - smooth[nrofsmooth].id = FindFace (q, 0); + smooth[nrofsmooth].id = face_find (q); q = p + 1; - smooth[nrofsmooth].smooth = FindFace (q, 0); + smooth[nrofsmooth].smooth = face_find (q); nrofsmooth++; } fclose (fp); @@ -433,18 +190,3 @@ return bp ? 1 : 0; } -/** - * Deallocates memory allocated by ReadBmapNames() and ReadSmooth(). - */ -void -free_all_images (void) -{ - int i; - - for (i = 0; i < nroffiles; i++) - free (xbm[i].name); - - delete[]xbm; - delete[]new_faces; - delete[]smooth; -}