1 /***********************************************************
2 * Artsoft Retro-Game Library *
3 *----------------------------------------------------------*
4 * (c) 1994-2002 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
20 /* ========================================================================= */
21 /* PLATFORM SPECIFIC IMAGE FUNCTIONS */
22 /* ========================================================================= */
24 #if defined(TARGET_X11)
26 /* for MS-DOS/Allegro, exclude all except newImage() and freeImage() */
28 Image *newImage(unsigned int width, unsigned int height, unsigned int depth)
31 unsigned int bytes_per_pixel = (depth + 7) / 8;
36 Error(ERR_EXIT, "images with more than 256 colors are not supported");
41 image = checked_calloc(sizeof(Image));
42 image->data = checked_calloc(width * height * bytes_per_pixel);
44 image->height = height;
46 image->bytes_per_pixel = bytes_per_pixel;
47 image->bytes_per_row = width * bytes_per_pixel;
50 for (i=0; i<MAX_COLORS; i++)
51 image->rgb.color_used[i] = FALSE;
53 image->type = (depth < 8 ? IMAGETYPE_BITMAP :
54 depth > 8 ? IMAGETYPE_TRUECOLOR : IMAGETYPE_RGB);
59 void freeImage(Image *image)
65 #if defined(PLATFORM_UNIX)
67 /* extra colors to try allocating in private color maps to minimize flashing */
68 #define NOFLASH_COLORS 256
70 /* architecture independent value <-> memory conversions;
71 note: the internal format is big endian */
73 #define memory_to_value(ptr, len) ( \
74 (len) == 1 ? (unsigned long)( *( (byte *)(ptr)) ) : \
75 (len) == 2 ? (unsigned long)(((unsigned long)(*( (byte *)(ptr)) ))<< 8) \
76 + ( *(((byte *)(ptr))+1) ) : \
77 (len) == 3 ? (unsigned long)(((unsigned long)(*( (byte *)(ptr)) ))<<16) \
78 + (((unsigned long)(*(((byte *)(ptr))+1)))<< 8) \
79 + ( *(((byte *)(ptr))+2) ) : \
80 (unsigned long)(((unsigned long)(*( (byte *)(ptr)) ))<<24) \
81 + (((unsigned long)(*(((byte *)(ptr))+1)))<<16) \
82 + (((unsigned long)(*(((byte *)(ptr))+2)))<< 8) \
83 + ( *(((byte *)(ptr))+3) ) )
86 #define value_to_memory(value, ptr, len) ( \
87 (len) == 1 ? (*( (byte *)(ptr) ) = ( value ) ) : \
88 (len) == 2 ? (*( (byte *)(ptr) ) = (((unsigned long)(value))>> 8), \
89 *(((byte *)(ptr))+1) = ( value ) ) : \
90 (len) == 3 ? (*( (byte *)(ptr) ) = (((unsigned long)(value))>>16), \
91 *(((byte *)(ptr))+1) = (((unsigned long)(value))>> 8), \
92 *(((byte *)(ptr))+2) = ( value ) ) : \
93 (*( (byte *)(ptr) ) = (((unsigned long)(value))>>24), \
94 *(((byte *)(ptr))+1) = (((unsigned long)(value))>>16), \
95 *(((byte *)(ptr))+2) = (((unsigned long)(value))>> 8), \
96 *(((byte *)(ptr))+3) = ( value ) ))
98 static Pixmap Image_to_Mask(Image *image, Display *display, Window window)
100 byte *src_ptr, *dst_ptr, *dst_ptr2;
101 unsigned int bytes_per_row;
102 unsigned int x, y, i;
107 bytes_per_row = (image->width + 7) / 8;
108 mask_data = checked_calloc(bytes_per_row * image->height);
110 src_ptr = image->data;
113 /* create bitmap data which can be used by 'XCreateBitmapFromData()'
114 * directly to create a pixmap of depth 1 for use as a clip mask for
115 * the corresponding image pixmap
118 for (y=0; y<image->height; y++)
120 bitmask = 0x01; /* start with leftmost bit in the byte */
121 dst_ptr2 = dst_ptr; /* start with leftmost byte in the row */
123 for (x=0; x<image->width; x++)
125 for (i=0; i<image->bytes_per_pixel; i++)
126 if (*src_ptr++) /* source pixel solid? (pixel index != 0) */
127 *dst_ptr2 |= bitmask; /* then write a bit into the image mask */
129 if ((bitmask <<= 1) == 0) /* bit at rightmost byte position reached? */
131 bitmask = 0x01; /* start again with leftmost bit position */
132 dst_ptr2++; /* continue with next byte in image mask */
136 dst_ptr += bytes_per_row; /* continue with leftmost byte of next row */
139 mask_pixmap = XCreateBitmapFromData(display, window, (char *)mask_data,
140 image->width, image->height);
146 static int bitsPerPixelAtDepth(Display *display, int screen, int depth)
148 XPixmapFormatValues *pixmap_format;
149 int i, num_pixmap_formats, bits_per_pixel = -1;
151 /* get Pixmap formats supported by the X server */
152 pixmap_format = XListPixmapFormats(display, &num_pixmap_formats);
154 /* find format that matches the given depth */
155 for (i=0; i<num_pixmap_formats; i++)
156 if (pixmap_format[i].depth == depth)
157 bits_per_pixel = pixmap_format[i].bits_per_pixel;
159 XFree(pixmap_format);
161 if (bits_per_pixel == -1)
162 Error(ERR_EXIT, "cannot find pixmap format for depth %d", depth);
164 return bits_per_pixel;
167 XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual,
168 Window window, GC gc, int depth, Image *image)
170 static XColor xcolor_private[NOFLASH_COLORS];
171 static int colorcell_used[NOFLASH_COLORS];
172 static Colormap global_cmap = 0;
173 static Pixel *global_cmap_index;
174 static int num_cmap_entries, free_cmap_entries;
175 static boolean private_cmap = FALSE;
176 Pixel *redvalue, *greenvalue, *bluevalue;
177 unsigned int display_bytes_per_pixel, display_bits_per_pixel;
178 unsigned int a, c = 0, x, y;
181 XImageInfo *ximageinfo;
182 byte *src_ptr, *dst_ptr;
183 char *error = "Image_to_Pixmap(): %s";
185 if (image->type == IMAGETYPE_TRUECOLOR && depth == 8)
187 SetError(error, "cannot handle true-color images on 8-bit display");
193 if (visual == DefaultVisual(display, screen))
194 global_cmap = DefaultColormap(display, screen);
197 global_cmap = XCreateColormap(display, RootWindow(display, screen),
203 xcolor.flags = DoRed | DoGreen | DoBlue;
204 redvalue = greenvalue = bluevalue = NULL;
205 ximageinfo = checked_malloc(sizeof(XImageInfo));
206 ximageinfo->display = display;
207 ximageinfo->depth = depth;
209 switch (visual->class)
215 unsigned int redcolors, greencolors, bluecolors;
216 unsigned int redstep, greenstep, bluestep;
217 unsigned int redbottom, greenbottom, bluebottom;
218 unsigned int redtop, greentop, bluetop;
220 redvalue = (Pixel *)checked_malloc(sizeof(Pixel) * 256);
221 greenvalue = (Pixel *)checked_malloc(sizeof(Pixel) * 256);
222 bluevalue = (Pixel *)checked_malloc(sizeof(Pixel) * 256);
224 ximageinfo->cmap = global_cmap;
226 retry_direct: /* tag we hit if a DirectColor allocation fails on
227 * default colormap */
229 /* calculate number of distinct colors in each band */
231 redcolors = greencolors = bluecolors = 1;
232 for (pixval=1; pixval; pixval <<= 1)
234 if (pixval & visual->red_mask)
236 if (pixval & visual->green_mask)
238 if (pixval & visual->blue_mask)
242 /* consistency check */
243 if (redcolors > visual->map_entries ||
244 greencolors > visual->map_entries ||
245 bluecolors > visual->map_entries)
246 Error(ERR_WARN, "inconsistency in color information");
248 redstep = 256 / redcolors;
249 greenstep = 256 / greencolors;
250 bluestep = 256 / bluecolors;
251 redbottom = greenbottom = bluebottom = 0;
252 redtop = greentop = bluetop = 0;
254 for (a=0; a<visual->map_entries; a++)
257 redtop = redbottom + redstep;
258 if (greenbottom < 256)
259 greentop = greenbottom + greenstep;
260 if (bluebottom < 256)
261 bluetop = bluebottom + bluestep;
263 xcolor.red = (redtop - 1) << 8;
264 xcolor.green = (greentop - 1) << 8;
265 xcolor.blue = (bluetop - 1) << 8;
266 if (!XAllocColor(display, ximageinfo->cmap, &xcolor))
268 /* if an allocation fails for a DirectColor default visual then
269 we should create a private colormap and try again. */
271 if ((visual->class == DirectColor) &&
272 (visual == DefaultVisual(display, screen)))
274 global_cmap = XCopyColormapAndFree(display, global_cmap);
275 ximageinfo->cmap = global_cmap;
281 /* something completely unexpected happened */
283 fprintf(stderr, "Image_to_Pixmap: XAllocColor failed on a TrueColor/Directcolor visual\n");
293 /* fill in pixel values for each band at this intensity */
295 while ((redbottom < 256) && (redbottom < redtop))
296 redvalue[redbottom++] = xcolor.pixel & visual->red_mask;
297 while ((greenbottom < 256) && (greenbottom < greentop))
298 greenvalue[greenbottom++] = xcolor.pixel & visual->green_mask;
299 while ((bluebottom < 256) && (bluebottom < bluetop))
300 bluevalue[bluebottom++] = xcolor.pixel & visual->blue_mask;
308 ximageinfo->cmap = global_cmap;
310 for (a=0; a<MAX_COLORS; a++)
317 if (!image->rgb.color_used[a])
320 xcolor.red = *(image->rgb.red + a);
321 xcolor.green = *(image->rgb.green + a);
322 xcolor.blue = *(image->rgb.blue + a);
324 /* look if this color already exists in our colormap */
325 if (!XAllocColor(display, ximageinfo->cmap, &xcolor))
330 Error(ERR_RETURN, "switching to private colormap");
332 /* we just filled up the default colormap -- get a private one
333 which contains all already allocated colors */
335 global_cmap = XCopyColormapAndFree(display, global_cmap);
336 ximageinfo->cmap = global_cmap;
339 /* allocate the rest of the color cells read/write */
341 (Pixel *)checked_malloc(sizeof(Pixel) * NOFLASH_COLORS);
342 for (i=0; i<NOFLASH_COLORS; i++)
343 if (!XAllocColorCells(display, global_cmap, FALSE, NULL, 0,
344 global_cmap_index + i, 1))
346 num_cmap_entries = free_cmap_entries = i;
349 printf("We've got %d free colormap entries.\n", free_cmap_entries);
352 /* to minimize colormap flashing, copy default colors and try
353 to keep them as near as possible to the old values */
355 for(i=0; i<num_cmap_entries; i++)
357 xcolor2.pixel = *(global_cmap_index + i);
358 XQueryColor(display, DefaultColormap(display, screen), &xcolor2);
359 XStoreColor(display, global_cmap, &xcolor2);
360 xcolor_private[xcolor2.pixel] = xcolor2;
361 colorcell_used[xcolor2.pixel] = FALSE;
364 /* now we have the default colormap private: all colors we
365 successfully allocated so far are read-only, which is okay,
366 because we don't want to change them anymore -- if we need
367 an existing color again, we get it by XAllocColor; all other
368 colors are read/write and we can set them by XStoreColor,
369 but we will try to overwrite those color cells with our new
370 color which are as close as possible to our new color */
373 /* look for an existing default color close the one we want */
380 for (i=num_cmap_entries-1; i>=0; i--)
382 xcolor2.pixel = *(global_cmap_index + i);
383 xcolor2 = xcolor_private[xcolor2.pixel];
385 if (colorcell_used[xcolor2.pixel])
388 if ((xcolor.red & mask) == (xcolor2.red & mask) &&
389 (xcolor.green & mask) == (xcolor2.green & mask) &&
390 (xcolor.blue & mask) == (xcolor2.blue & mask))
393 printf("replacing color cell %ld with a close color\n",
404 mask = (mask << 1) & 0xffff;
407 if (!color_found) /* no more free color cells */
409 SetError(error, "cannot allocate enough color cells");
413 xcolor.pixel = xcolor2.pixel;
414 xcolor_private[xcolor.pixel] = xcolor;
415 colorcell_used[xcolor.pixel] = TRUE;
416 XStoreColor(display, ximageinfo->cmap, &xcolor);
420 *(ximageinfo->index + a) = xcolor.pixel;
424 printf("still %d free colormap entries\n", free_cmap_entries);
427 ximageinfo->no = a; /* number of pixels allocated for this image */
431 Error(ERR_RETURN,"DirectColor, TrueColor or PseudoColor display needed");
432 SetError(error, "display class not supported");
438 debug_print_timestamp(2, " ALLOCATING IMAGE COLORS: ");
441 /* create XImage from internal image structure and convert it to Pixmap */
443 display_bits_per_pixel = bitsPerPixelAtDepth(display, screen, depth);
444 display_bytes_per_pixel = (display_bits_per_pixel + 7) / 8;
446 ximage = XCreateImage(display, visual, depth, ZPixmap,
447 0, NULL, image->width, image->height,
448 8, image->width * display_bytes_per_pixel);
450 checked_malloc(image->width * image->height * display_bytes_per_pixel);
451 ximage->byte_order = MSBFirst;
453 src_ptr = image->data;
454 dst_ptr = (byte *)ximage->data;
456 switch (visual->class)
467 for (y=0; y<image->height; y++) /* general case */
469 for (x=0; x<image->width; x++)
473 redvalue[image->rgb.red[pixval] >> 8] |
474 greenvalue[image->rgb.green[pixval] >> 8] |
475 bluevalue[image->rgb.blue[pixval] >> 8];
476 value_to_memory(pixval, dst_ptr, display_bytes_per_pixel);
477 dst_ptr += display_bytes_per_pixel;
484 case IMAGETYPE_TRUECOLOR:
486 for (y=0; y<image->height; y++) /* general case */
488 for (x=0; x<image->width; x++)
490 pixval = memory_to_value(src_ptr, image->bytes_per_pixel);
492 redvalue[TRUECOLOR_RED(pixval)] |
493 greenvalue[TRUECOLOR_GREEN(pixval)] |
494 bluevalue[TRUECOLOR_BLUE(pixval)];
495 value_to_memory(pixval, dst_ptr, display_bytes_per_pixel);
496 src_ptr += image->bytes_per_pixel;
497 dst_ptr += display_bytes_per_pixel;
505 Error(ERR_RETURN, "RGB or TrueColor image needed");
506 SetError(error, "image type not supported");
516 if (display_bytes_per_pixel == 1) /* special case */
518 for (y=0; y<image->height; y++)
519 for (x=0; x<image->width; x++)
520 *dst_ptr++ = ximageinfo->index[c + *src_ptr++];
522 else /* general case */
524 for (y=0; y<image->height; y++)
526 for (x=0; x<image->width; x++)
528 value_to_memory(ximageinfo->index[c + *src_ptr++],
529 dst_ptr, display_bytes_per_pixel);
530 dst_ptr += display_bytes_per_pixel;
539 Error(ERR_RETURN,"DirectColor, TrueColor or PseudoColor display needed");
540 SetError(error, "display class not supported");
547 free((byte *)redvalue);
548 free((byte *)greenvalue);
549 free((byte *)bluevalue);
553 debug_print_timestamp(2, " CONVERTING IMAGE TO XIMAGE:");
556 ximageinfo->pixmap = XCreatePixmap(display, window,
557 ximage->width, ximage->height,
560 XPutImage(ximageinfo->display, ximageinfo->pixmap, gc,
561 ximage, 0, 0, 0, 0, ximage->width, ximage->height);
563 XDestroyImage(ximage);
569 -----------------------------------------------------------------------------
572 Important note: The scaling code currently only supports scaling down the
573 image by a power of 2 -- scaling up is currently not supported at all!
574 -----------------------------------------------------------------------------
577 void ZoomPixmap(Display *display, GC gc, Pixmap src_pixmap, Pixmap dst_pixmap,
578 int src_width, int src_height,
579 int dst_width, int dst_height)
581 XImage *src_ximage, *dst_ximage;
582 byte *src_ptr, *dst_ptr;
586 int zoom_factor = src_width / dst_width; /* currently very limited! */
587 int row_skip, col_skip;
589 /* copy source pixmap to temporary image */
590 src_ximage = XGetImage(display, src_pixmap, 0, 0,
591 src_width, src_height, AllPlanes, ZPixmap);
593 bits_per_pixel = src_ximage->bits_per_pixel;
594 bytes_per_pixel = (bits_per_pixel + 7) / 8;
596 dst_ximage = XCreateImage(display, visual, src_ximage->depth, ZPixmap,
597 0, NULL, dst_width, dst_height,
598 8, dst_width * bytes_per_pixel);
600 checked_malloc(dst_width * dst_height * bytes_per_pixel);
601 dst_ximage->byte_order = src_ximage->byte_order;
603 src_ptr = (byte *)src_ximage->data;
604 dst_ptr = (byte *)dst_ximage->data;
606 col_skip = (zoom_factor - 1) * bytes_per_pixel;
607 row_skip = col_skip * src_width;
609 /* scale image down by scaling factor 'zoom_factor' */
610 for (y=0; y < src_height; y += zoom_factor, src_ptr += row_skip)
611 for (x=0; x < src_width; x += zoom_factor, src_ptr += col_skip)
612 for (i=0; i<bytes_per_pixel; i++)
613 *dst_ptr++ = *src_ptr++;
615 /* copy scaled image to destination pixmap */
616 XPutImage(display, dst_pixmap, gc, dst_ximage, 0, 0, 0, 0,
617 MIN(src_width, dst_width), MIN(src_height, dst_height));
619 /* free temporary images */
620 XDestroyImage(src_ximage);
621 XDestroyImage(dst_ximage);
624 void freeXImage(Image *image, XImageInfo *ximageinfo)
626 if (ximageinfo->index != NULL && ximageinfo->no > 0)
627 XFreeColors(ximageinfo->display, ximageinfo->cmap, ximageinfo->index,
629 /* this ^^^^^^^^^^^^^^ is wrong, because the used color cells
630 * are somewhere between 0 and MAX_COLORS; there are indeed 'ximageinfo->no'
631 * used color cells, but they are not at array position 0 - 'ximageinfo->no'
637 int Read_PCX_to_Pixmap(Display *display, Window window, GC gc, char *filename,
638 Pixmap *pixmap, Pixmap *pixmap_mask)
641 XImageInfo *ximageinfo;
647 debug_print_timestamp(2, NULL); /* initialize timestamp function */
650 /* read the graphic file in PCX format to image structure */
651 if ((image = Read_PCX_to_Image(filename)) == NULL)
655 printf("%s:\n", filename);
656 debug_print_timestamp(2, " READING PCX FILE TO IMAGE: ");
659 screen = DefaultScreen(display);
660 visual = DefaultVisual(display, screen);
661 depth = DefaultDepth(display, screen);
663 /* convert image structure to X11 Pixmap */
664 if (!(ximageinfo = Image_to_Pixmap(display, screen, visual,
665 window, gc, depth, image)))
669 return PCX_OtherError;
672 /* if a private colormap has been created, install it */
673 if (ximageinfo->cmap != DefaultColormap(display, screen))
674 XSetWindowColormap(display, window, ximageinfo->cmap);
677 debug_print_timestamp(2, " CONVERTING IMAGE TO PIXMAP:");
680 /* create clip mask for the image */
681 ximageinfo->pixmap_mask = Image_to_Mask(image, display, window);
684 debug_print_timestamp(2, " CONVERTING IMAGE TO MASK: ");
687 *pixmap = ximageinfo->pixmap;
688 *pixmap_mask = ximageinfo->pixmap_mask;
690 /* free generic image and ximageinfo after native Pixmap has been created */
697 #endif /* PLATFORM_UNIX */
698 #endif /* TARGET_X11 */
701 /* ========================================================================= */
702 /* PLATFORM INDEPENDANT IMAGE FUNCTIONS */
703 /* ========================================================================= */
707 char *source_filename;
711 boolean contains_small_images;
713 typedef struct ImageInfo ImageInfo;
715 static struct ArtworkListInfo *image_info = NULL;
717 static void *Load_PCX(char *filename)
722 printf("loading PCX file '%s'\n", filename);
725 img_info = checked_calloc(sizeof(ImageInfo));
727 if ((img_info->bitmap = LoadImage(filename)) == NULL)
729 Error(ERR_WARN, "cannot read image file '%s': LoadImage() failed: %s",
730 filename, GetError());
735 img_info->source_filename = getStringCopy(filename);
737 img_info->contains_small_images = FALSE;
742 static void FreeImage(void *ptr)
744 ImageInfo *image = (ImageInfo *)ptr;
750 FreeBitmap(image->bitmap);
752 if (image->source_filename)
753 free(image->source_filename);
758 int getImageListSize()
760 return (image_info->num_file_list_entries +
761 image_info->num_dynamic_file_list_entries);
764 struct FileInfo *getImageListEntry(int pos)
766 int num_list_entries = image_info->num_file_list_entries;
767 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
769 return (pos < num_list_entries ? &image_info->file_list[list_pos] :
770 &image_info->dynamic_file_list[list_pos]);
773 static ImageInfo *getImageInfoEntryFromImageID(int pos)
775 int num_list_entries = image_info->num_file_list_entries;
776 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
777 ImageInfo **img_info =
778 (ImageInfo **)(pos < num_list_entries ? image_info->artwork_list :
779 image_info->dynamic_artwork_list);
781 return img_info[list_pos];
784 Bitmap *getBitmapFromImageID(int pos)
787 int num_list_entries = image_info->num_file_list_entries;
788 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
789 ImageInfo **img_info =
790 (ImageInfo **)(pos < num_list_entries ? image_info->artwork_list :
791 image_info->dynamic_artwork_list);
793 return (img_info[list_pos] != NULL ? img_info[list_pos]->bitmap : NULL);
795 ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
797 return (img_info != NULL ? img_info->bitmap : NULL);
801 char *getTokenFromImageID(int graphic)
803 struct FileInfo *file_list = (struct FileInfo *)image_info->file_list;
805 return file_list[graphic].token;
808 char *getImageConfigFilename()
810 return getCustomArtworkConfigFilename(image_info->type);
813 int getImageListPropertyMappingSize()
815 return image_info->num_property_mapping_entries;
818 struct PropertyMapping *getImageListPropertyMapping()
820 return image_info->property_mapping;
823 void InitImageList(struct ConfigInfo *config_list, int num_file_list_entries,
824 struct ConfigInfo *config_suffix_list,
825 char **base_prefixes, char **ext1_suffixes,
826 char **ext2_suffixes, char **ext3_suffixes,
827 char **ignore_tokens)
831 image_info = checked_calloc(sizeof(struct ArtworkListInfo));
832 image_info->type = ARTWORK_TYPE_GRAPHICS;
834 /* ---------- initialize file list and suffix lists ---------- */
836 image_info->num_file_list_entries = num_file_list_entries;
837 image_info->num_dynamic_file_list_entries = 0;
839 image_info->file_list =
840 getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
841 num_file_list_entries);
842 image_info->dynamic_file_list = NULL;
844 image_info->num_suffix_list_entries = 0;
845 for (i=0; config_suffix_list[i].token != NULL; i++)
846 image_info->num_suffix_list_entries++;
848 image_info->suffix_list = config_suffix_list;
850 /* ---------- initialize base prefix and suffixes lists ---------- */
852 image_info->num_base_prefixes = 0;
853 for (i=0; base_prefixes[i] != NULL; i++)
854 image_info->num_base_prefixes++;
856 image_info->num_ext1_suffixes = 0;
857 for (i=0; ext1_suffixes[i] != NULL; i++)
858 image_info->num_ext1_suffixes++;
860 image_info->num_ext2_suffixes = 0;
861 for (i=0; ext2_suffixes[i] != NULL; i++)
862 image_info->num_ext2_suffixes++;
864 image_info->num_ext3_suffixes = 0;
865 for (i=0; ext3_suffixes[i] != NULL; i++)
866 image_info->num_ext3_suffixes++;
868 image_info->num_ignore_tokens = 0;
869 for (i=0; ignore_tokens[i] != NULL; i++)
870 image_info->num_ignore_tokens++;
872 image_info->base_prefixes = base_prefixes;
873 image_info->ext1_suffixes = ext1_suffixes;
874 image_info->ext2_suffixes = ext2_suffixes;
875 image_info->ext3_suffixes = ext3_suffixes;
876 image_info->ignore_tokens = ignore_tokens;
878 image_info->num_property_mapping_entries = 0;
880 image_info->property_mapping = NULL;
882 /* ---------- initialize artwork reference and content lists ---------- */
884 image_info->sizeof_artwork_list_entry = sizeof(ImageInfo *);
886 image_info->artwork_list =
887 checked_calloc(num_file_list_entries * sizeof(ImageInfo *));
888 image_info->dynamic_artwork_list = NULL;
890 image_info->content_list = NULL;
892 /* ---------- initialize artwork loading/freeing functions ---------- */
894 image_info->load_artwork = Load_PCX;
895 image_info->free_artwork = FreeImage;
898 void ReloadCustomImages()
901 printf("DEBUG: reloading images '%s' ...\n", artwork.gfx_current_identifier);
904 LoadArtworkConfig(image_info);
905 ReloadCustomArtworkList(image_info);
908 void CreateImageWithSmallImages(int pos)
910 ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
912 if (img_info == NULL || img_info->contains_small_images)
915 CreateBitmapWithSmallBitmaps(img_info->bitmap);
917 img_info->contains_small_images = TRUE;
920 printf("CreateImageWithSmallImages: '%s' done\n", img_info->source_filename);
926 FreeCustomArtworkLists(image_info);