--- deliantra/server/common/image.C 2006/09/04 11:07:59 1.4 +++ deliantra/server/common/image.C 2007/02/15 18:09:33 1.17 @@ -1,36 +1,34 @@ /* - * static char *rcsid_image_c = - * "$Id: image.C,v 1.4 2006/09/04 11:07:59 root Exp $"; + * 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 */ -/* - CrossFire, A Multiplayer game for X-windows - - 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 crossfire-devel@real-time.com -*/ - #include #include -New_Face *new_faces; +#include "crc.h" + +facetile *new_faces; /* bmappair and xbm are used when looking for the image id numbers * of a face by name. xbm is sorted alphabetically so that bsearch @@ -50,15 +48,9 @@ unsigned int number; }; -void free (bmappair *); // guard to catch free when delete should be used - -static struct bmappair *xbm=NULL; - -/* Following can just as easily be pointers, but - * it is easier to keep them like this. - */ -New_Face *blank_face, *dark_faces[3], *empty_face, *smooth_face; +static struct bmappair *xbm = NULL; +facetile *blank_face, *dark_faces[3], *empty_face, *smooth_face; /* nroffiles is the actual number of bitmaps defined. * nrofpixmaps is the number of bitmaps loaded. With @@ -78,18 +70,16 @@ */ struct smoothing : zero_initialised { - uint16 id; - uint16 smooth; + uint16 id; + uint16 smooth; }; -void free (smoothing *); // guard to catch free when delete should be used - /** * 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; +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 @@ -98,109 +88,132 @@ * 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 */ + "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 (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->idid) - return -1; - if (b->idid) - return 1; - return 0; +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) + 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) { +static uint8 +find_color (const char *name) +{ uint8 i; - for(i=0;ivisibility=0; + 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 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); + else + LOG (llevDebug, "Got unknown line in faces file: %s\n", buf); } - LOG(llevDebug,"done\n"); - fclose(fp); + + LOG (llevDebug, "done\n"); + fclose (fp); } /* This reads the bmaps file to get all the bitmap names and @@ -208,109 +221,113 @@ * independent (ie, what display the person is on will not make a * difference.) */ +void +ReadBmapNames (void) +{ + 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); + } -void ReadBmapNames (void) { - char buf[MAX_BUF], *p, *q; - FILE *fp; - int value, nrofbmaps = 0, i; - size_t l; - - bmaps_checksum=0; - sprintf (buf,"%s/bmaps", settings.datadir); - LOG(llevDebug,"Reading bmaps from %s...",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; } - - /* 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_local(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. - */ - ROTATE_RIGHT(bmaps_checksum); - bmaps_checksum += value & 0xff; - bmaps_checksum &= 0xffffffff; - - ROTATE_RIGHT(bmaps_checksum); - bmaps_checksum += (value >> 8) & 0xff; - bmaps_checksum &= 0xffffffff; - for (l=0; l= nrofpixmaps) - nrofpixmaps = value+1; - } - fclose(fp); + LOG (llevDebug, "done (got %d/%d/%d)\n", nrofpixmaps, nrofbmaps, nroffiles); - LOG(llevDebug,"done (got %d/%d/%d)\n",nrofpixmaps,nrofbmaps,nroffiles); + new_faces = new facetile[nrofpixmaps]; - new_faces = new New_Face [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; + 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; } - // non-pod datatype, likely not allowed - qsort (xbm, nroffiles, sizeof(struct bmappair), (int (*)(const void*, const void*))compar); + 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(); + 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); + 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; + 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)]; + /* 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)]; - smooth_face = &new_faces[FindFace(SMOOTH_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)]; + + smooth_face = &new_faces[FindFace (SMOOTH_FACE_NAME, 0)]; + + bmaps_checksum = crc; } /* This returns an the face number of face 'name'. Number is constant @@ -326,18 +343,22 @@ * (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 ((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); +int +FindFace (const char *name, int error) +{ + struct bmappair *bp, tmp; + char *p; - return bp ? bp->number : error; + 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; } /* Reads the smooth file to know how to smooth datas. @@ -347,45 +368,48 @@ * 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; - - bmaps_checksum=0; - sprintf (buf,"%s/smooth", settings.datadir); - LOG(llevDebug,"Reading smooth from %s...",buf); - if ((fp=fopen(buf,"r"))==NULL) { - LOG(llevError, "Cannot open smooth file %s: %s\n", strerror(errno)); - exit(-1); +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=FindFace(q,0); - q=p+1; - smooth[nrofsmooth].smooth=FindFace(q,0); - nrofsmooth++; + /* 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 = FindFace (q, 0); + q = p + 1; + smooth[nrofsmooth].smooth = FindFace (q, 0); + nrofsmooth++; } - fclose(fp); + 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; + LOG (llevDebug, "done (got %d smooth entries)\n", nrofsmooth); + qsort (smooth, nrofsmooth, sizeof (struct smoothing), (int (*)(const void *, const void *)) compar_smooth); + return nrofsmooth; } /** @@ -397,29 +421,32 @@ * * @return 1=smooth face found, 0=no smooth face found */ -int FindSmooth (uint16 face, uint16* smoothed) { - struct smoothing *bp, tmp; +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; + 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; } /** * Deallocates memory allocated by ReadBmapNames() and ReadSmooth(). */ -void free_all_images(void) +void +free_all_images (void) { - int i; + int i; - for (i=0; i