version 1.2 | | version 1.3 |
---|
| | |
/* | | /* |
* static char *rcsid_xutil_c = | | * static char *rcsid_xutil_c = |
* "$Id: xutil.c,v 1.2 1999/07/13 06:02:43 cvs Exp $"; | | * "$Id: xutil.c,v 1.3 2000/05/13 23:44:43 cvs Exp $"; |
*/ | | */ |
| | |
/* | | /* |
CrossFire, A Multiplayer game for X-windows | | CrossFire, A Multiplayer game for X-windows |
| | |
Copyright (C) 1994 Mark Wedel | | Copyright (C) 2000 Mark Wedel |
Copyright (C) 1992 Frank Tore Johansen | | Copyright (C) 1992 Frank Tore Johansen |
| | |
This program is free software; you can redistribute it and/or modify | | This program is free software; you can redistribute it and/or modify |
| | |
along with this program; if not, write to the Free Software | | along with this program; if not, write to the Free Software |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| | |
The author can be reached via e-mail to master@rahul.net | | The author can be reached via e-mail to mwedel@scruz.net |
*/ | | */ |
| | |
#include <global.h> | | #include <global.h> |
| | |
/* | | /* |
* ReadPixmaps(): When color pixmaps are used instead of fonts, this function | | * ReadPixmaps(): When color pixmaps are used instead of fonts, this function |
* does the actual reading of pixmap-file. This function is based largely on | | * does the actual reading of pixmap-file. This function is based largely on |
* the ReadBitmaps function. By Mark Wedel (master@rahul.net) | | * the ReadBitmaps function. |
*/ | | */ |
| | |
/* New method: Pixmaps are stored as a montage on the disk (in several | | /* New method: Pixmaps are stored as a montage on the disk (in several |
| | |
* large numbers of pixmaps. | | * large numbers of pixmaps. |
* | | * |
* Return true if we have gone to a private colormap. | | * Return true if we have gone to a private colormap. |
| | * |
| | * type is type of images to load. If Dm_Bitmaps, cmap, and masks |
| | * can be null. |
*/ | | */ |
| | |
int ReadPixmaps(Display *gdisp, Pixmap **pixmaps, Pixmap **masks, | | int ReadImages(Display *gdisp, Pixmap **pixmaps, Pixmap **masks, |
Colormap *cmap) { | | Colormap *cmap, enum DisplayMode type) { |
#ifdef HAVE_LIBXPM | | #ifdef HAVE_LIBXPM |
| | |
Window root = RootWindow (gdisp,DefaultScreen(gdisp)); | | Window root = RootWindow (gdisp,DefaultScreen(gdisp)); |
XpmAttributes xpmatribs; | | XpmAttributes xpmatribs; |
int use_private_cmap=0,num, compressed, len,i, error; | | int use_private_cmap=0,num, compressed, len,i, error; |
FILE *infile; | | FILE *infile; |
char buf[MAX_BUF], *cur, databuf[HUGE_BUF], filename[MAX_BUF]; | | char *cp, databuf[HUGE_BUF], filename[MAX_BUF]; |
| | |
/* This function is called before the game gc's are created. So | | /* This function is called before the game gc's are created. So |
* we create one for our own use here. | | * we create one for our own use here. |
| | |
* the pixmap data. Therefor, only space for the pointers to that data | | * the pixmap data. Therefor, only space for the pointers to that data |
* needs to be allocated. The same might apply for the function | | * needs to be allocated. The same might apply for the function |
* that creates bitmaps below, but I am not as sure in that case. | | * that creates bitmaps below, but I am not as sure in that case. |
* Mark Wedel (master@rahul.net) | | * Mark Wedel |
*/ | | */ |
| | |
*pixmaps = (Pixmap *) malloc(sizeof(Pixmap *) * nrofpixmaps); | | *pixmaps = (Pixmap *) malloc(sizeof(Pixmap *) * nrofpixmaps); |
| | if (type==Dm_Pixmap) |
*masks = (Pixmap *) malloc(sizeof(Pixmap *) * nrofpixmaps); | | *masks = (Pixmap *) malloc(sizeof(Pixmap *) * nrofpixmaps); |
| | |
for (i=0; i < nrofpixmaps; i++) | | for (i=0; i < nrofpixmaps; i++) |
(*pixmaps)[i] = 0; | | (*pixmaps)[i] = 0; |
| | |
LOG(llevDebug,"Building color pixmaps..."); | | LOG(llevDebug,"Building images..."); |
| | |
| | if (type==Dm_Pixmap) |
sprintf(filename,"%s/crossfire.xpm",settings.datadir); | | sprintf(filename,"%s/crossfire.xpm",settings.datadir); |
| | else if (type==Dm_Bitmap) |
| | sprintf(filename,"%s/crossfire.xbm",settings.datadir); |
| | |
if ((infile = open_and_uncompress(filename,0,&compressed))==NULL) { | | if ((infile = open_and_uncompress(filename,0,&compressed))==NULL) { |
LOG(llevError,"Unable to open %s\n", filename); | | LOG(llevError,"Unable to open %s\n", filename); |
abort(); | | abort(); |
} | | } |
i=0; | | i=0; |
while(1) { | | while (fgets(databuf,MAX_BUF,infile)) { |
if (!fgets(filename,MAX_BUF,infile)) break; | | |
| | |
/* First, verify that that image header line is OK */ | | /* First, verify that that image header line is OK */ |
if(strncmp(filename,"ESRV_XPM ",9)!=0 || filename[14] != ' ') { | | if(strncmp(databuf,"IMAGE ",6)!=0) { |
fprintf(stderr,"whoa, bad esrv_xpm line; not ESRV_XPM ...\n%s",filename); | | LOG(llevError,"ReadImages:Bad image line - not IMAGE, instead\n%s",databuf); |
abort(); | | abort(); |
} | | } |
num = atoi(filename+9); | | num = atoi(databuf+6); |
if (num<0 || num > nrofpixmaps) { | | if (num<0 || num > nrofpixmaps) { |
LOG(llevError,"Pixmap number less than zero: %d, %s\n",num, filename); | | LOG(llevError,"Pixmap number less than zero: %d, %s\n",num, databuf); |
abort(); | | abort(); |
} | | } |
cur = databuf; | | /* Skip accross the number data */ |
/* Now read in all the image data */ | | for (cp=databuf+6; *cp!=' '; cp++) ; |
while(1) { | | len = atoi(cp); |
fgets(buf,500,infile); | | if (len==0 || len>HUGE_BUF) { |
if (*buf == '\0') { | | LOG(llevError,"ReadImages: length not valid: %d\n%s", |
fprintf(stderr,"whoa, pixmap #%d not terminated??\n",num); | | len,databuf); |
abort(); | | abort(); |
} | | } |
if (strcmp(buf,"ESRV_XPM_END\n")==0) | | if (fread(databuf, 1, len, infile)!=len) { |
break; | | LOG(llevError,"read_client_images: Did not read desired amount of data, wanted %d\n%s", |
len = strlen(buf); | | len, databuf); |
if (cur+len > databuf+HUGE_BUF) { | | |
LOG(llevError,"Overflow of MAX_BUF in read_client_images, image %d\n", num); | | |
abort(); | | abort(); |
} | | } |
strcpy(cur,buf); | | |
cur += len; | | |
} | | |
i++; | | i++; |
if (!(i % 100)) LOG(llevDebug,"."); | | if (!(i % 100)) LOG(llevDebug,"."); |
| | |
| | if (type==Dm_Pixmap) { |
again: error=XpmCreatePixmapFromBuffer(gdisp, root, databuf, | | again: error=XpmCreatePixmapFromBuffer(gdisp, root, databuf, |
&(*pixmaps)[num], &(*masks)[num], &xpmatribs); | | &(*pixmaps)[num], &(*masks)[num], &xpmatribs); |
if (error!=XpmSuccess) { | | if (error!=XpmSuccess) { |
| | |
use_private_cmap=1; | | use_private_cmap=1; |
goto again; | | goto again; |
} | | } |
LOG(llevError,"Error creating pixmap %s, error %d.\n",filename, error); | | LOG(llevError,"Error creating pixmap %d, error %d.\n",num, error); |
| | } |
| | } else if (type==Dm_Bitmap) { |
| | (*pixmaps)[num] = XCreateBitmapFromData |
| | (gdisp, RootWindow (gdisp, DefaultScreen(gdisp)), databuf, 24, 24); |
| | |
| | if ((*pixmaps)[num]==0) { |
| | LOG(llevError,"Warning: Cannot create Pixmap %d\n",i); |
| | } |
} | | } |
} | | } |
close_and_delete(infile, compressed); | | close_and_delete(infile, compressed); |
| | |
} | | } |
| | |
/* | | /* |
* ReadBitmaps(): When bitmaps are used instead of fonts, this function | | |
* does the actual reading of bitmap-file, and returns the | | |
* bitmaps array. It assumes the bitmap file found in the LIBDIR | | |
* directory. | | |
*/ | | |
| | |
| | |
Pixmap *ReadBitmaps(Display *d) { | | |
char buf[MAX_BUF]; | | |
FILE *fp; | | |
int i, count = 0,comp; | | |
Pixmap *pixmaps; | | |
| | |
if (!nrofpixmaps) | | |
nrofpixmaps = ReadBmapNames (); | | |
| | |
pixmaps = (Pixmap *) malloc(sizeof(Pixmap) * nrofpixmaps); | | |
for (i=0; i < nrofpixmaps; i++) | | |
pixmaps[i] = 0; | | |
| | |
sprintf (buf,"%s/crossfire.cfb",settings.datadir); | | |
if ((fp = open_and_uncompress(buf,0,&comp))==NULL) { | | |
perror("Can't open crossfire.cfb file"); | | |
exit(-1); | | |
} | | |
| | |
LOG(llevDebug,"Building ximages..."); | | |
for (i=0; i<nroffiles; i++) { | | |
if(pixmaps[i] != 0) { | | |
LOG(llevError,"Warning: two entries in bmaps: %d\n",i); | | |
continue; | | |
} | | |
| | |
if (fread (buf, 24 * 3, 1, fp) != 1) { | | |
LOG(llevError,"Warning: cannot read from file\n"); | | |
break; | | |
} | | |
| | |
pixmaps[i] = XCreateBitmapFromData | | |
(d, RootWindow (d, DefaultScreen(d)), buf, 24, 24); | | |
| | |
if (!pixmaps[i]) { | | |
LOG(llevError,"Warning: Cannot create Pixmap %d\n",i); | | |
pixmaps[i] = 0; | | |
} | | |
| | |
if(++count > CHECK_ACTIVE_MAPS/10) { | | |
printf ("."); | | |
fflush (stdout); | | |
count = 0; | | |
(*process_active_maps_func)(); | | |
} | | |
} | | |
close_and_delete(fp, comp); | | |
| | |
LOG(llevDebug,"done\n"); | | |
| | |
/* | | |
* Now fill out the unused holes with pointers to a blank pixmap | | |
* to avoid crashes in case trying to draw a nonexistant pixmap. | | |
*/ | | |
for (i = 0; i < nrofpixmaps; i++) | | |
if (pixmaps[i] == 0) | | |
pixmaps[i] = pixmaps[blank_face->number]; | | |
return pixmaps; | | |
} | | |
| | |
| | |
/* | | |
* allocate_colors() tries to get enough colors for the game-window. | | * allocate_colors() tries to get enough colors for the game-window. |
* If it fails, it tries to use a private colormap. | | * If it fails, it tries to use a private colormap. |
* If that also fails, it return 1, indicating to the calling | | * If that also fails, it return 1, indicating to the calling |