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 X11DestroyImage(ximage);
569 -----------------------------------------------------------------------------
572 Important note: The scaling code currently only supports scaling of the image
573 up or down by a power of 2 -- other scaling factors currently not supported!
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;
587 boolean scale_down = (src_width > dst_width);
590 int zoom_factor = src_width / dst_width; /* currently very limited! */
592 int row_skip, col_skip;
596 zoom_factor = src_width / dst_width;
598 /* adjust source image size to integer multiple of destination size */
599 src_width = dst_width * zoom_factor;
600 src_height = dst_height * zoom_factor;
604 zoom_factor = dst_width / src_width;
606 /* no adjustment needed when scaling up (some pixels may be left blank) */
609 /* copy source pixmap to temporary image */
610 src_ximage = XGetImage(display, src_pixmap, 0, 0, src_width, src_height,
613 bits_per_pixel = src_ximage->bits_per_pixel;
614 bytes_per_pixel = (bits_per_pixel + 7) / 8;
616 dst_ximage = XCreateImage(display, visual, src_ximage->depth, ZPixmap,
617 0, NULL, dst_width, dst_height,
618 8, dst_width * bytes_per_pixel);
620 checked_malloc(dst_width * dst_height * bytes_per_pixel);
621 dst_ximage->byte_order = src_ximage->byte_order;
623 src_ptr = (byte *)src_ximage->data;
624 dst_ptr = (byte *)dst_ximage->data;
628 col_skip = (zoom_factor - 1) * bytes_per_pixel;
629 row_skip = col_skip * src_width;
631 /* scale image down by scaling factor 'zoom_factor' */
632 for (y = 0; y < src_height; y += zoom_factor, src_ptr += row_skip)
633 for (x = 0; x < src_width; x += zoom_factor, src_ptr += col_skip)
634 for (i = 0; i < bytes_per_pixel; i++)
635 *dst_ptr++ = *src_ptr++;
639 row_skip = src_width * bytes_per_pixel;
641 /* scale image up by scaling factor 'zoom_factor' */
642 for (y = 0; y < src_height; y++)
644 for (yy = 0; yy < zoom_factor; yy++)
649 for (x = 0; x < src_width; x++)
651 for (xx = 0; xx < zoom_factor; xx++)
652 for (i = 0; i < bytes_per_pixel; i++)
653 *dst_ptr++ = *(src_ptr + i);
661 /* copy scaled image to destination pixmap */
662 XPutImage(display, dst_pixmap, gc, dst_ximage, 0, 0, 0, 0,
663 dst_width, dst_height);
665 /* free temporary images */
666 X11DestroyImage(src_ximage);
667 X11DestroyImage(dst_ximage);
670 void freeXImage(Image *image, XImageInfo *ximageinfo)
672 if (ximageinfo->index != NULL && ximageinfo->no > 0)
673 XFreeColors(ximageinfo->display, ximageinfo->cmap, ximageinfo->index,
675 /* this ^^^^^^^^^^^^^^ is wrong, because the used color cells
676 * are somewhere between 0 and MAX_COLORS; there are indeed 'ximageinfo->no'
677 * used color cells, but they are not at array position 0 - 'ximageinfo->no'
683 int Read_PCX_to_Pixmap(Display *display, Window window, GC gc, char *filename,
684 Pixmap *pixmap, Pixmap *pixmap_mask)
687 XImageInfo *ximageinfo;
693 debug_print_timestamp(2, NULL); /* initialize timestamp function */
696 /* read the graphic file in PCX format to image structure */
697 if ((image = Read_PCX_to_Image(filename)) == NULL)
701 printf("%s:\n", filename);
702 debug_print_timestamp(2, " READING PCX FILE TO IMAGE: ");
705 screen = DefaultScreen(display);
706 visual = DefaultVisual(display, screen);
707 depth = DefaultDepth(display, screen);
709 /* convert image structure to X11 Pixmap */
710 if (!(ximageinfo = Image_to_Pixmap(display, screen, visual,
711 window, gc, depth, image)))
715 return PCX_OtherError;
718 /* if a private colormap has been created, install it */
719 if (ximageinfo->cmap != DefaultColormap(display, screen))
720 XSetWindowColormap(display, window, ximageinfo->cmap);
723 debug_print_timestamp(2, " CONVERTING IMAGE TO PIXMAP:");
726 /* create clip mask for the image */
727 ximageinfo->pixmap_mask = Image_to_Mask(image, display, window);
730 debug_print_timestamp(2, " CONVERTING IMAGE TO MASK: ");
733 *pixmap = ximageinfo->pixmap;
734 *pixmap_mask = ximageinfo->pixmap_mask;
736 /* free generic image and ximageinfo after native Pixmap has been created */
743 #endif /* PLATFORM_UNIX */
744 #endif /* TARGET_X11 */
747 /* ========================================================================= */
748 /* PLATFORM INDEPENDENT IMAGE FUNCTIONS */
749 /* ========================================================================= */
753 char *source_filename;
757 boolean contains_small_images;
759 typedef struct ImageInfo ImageInfo;
761 static struct ArtworkListInfo *image_info = NULL;
763 static void *Load_PCX(char *filename)
768 printf("loading PCX file '%s'\n", filename);
771 img_info = checked_calloc(sizeof(ImageInfo));
773 if ((img_info->bitmap = LoadImage(filename)) == NULL)
775 Error(ERR_WARN, "cannot load image file '%s': LoadImage() failed: %s",
776 filename, GetError());
781 img_info->source_filename = getStringCopy(filename);
783 img_info->contains_small_images = FALSE;
788 static void FreeImage(void *ptr)
790 ImageInfo *image = (ImageInfo *)ptr;
796 FreeBitmap(image->bitmap);
798 if (image->source_filename)
799 free(image->source_filename);
804 int getImageListSize()
806 return (image_info->num_file_list_entries +
807 image_info->num_dynamic_file_list_entries);
810 struct FileInfo *getImageListEntry(int pos)
812 int num_list_entries = image_info->num_file_list_entries;
813 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
815 return (pos < num_list_entries ? &image_info->file_list[list_pos] :
816 &image_info->dynamic_file_list[list_pos]);
819 static ImageInfo *getImageInfoEntryFromImageID(int pos)
821 int num_list_entries = image_info->num_file_list_entries;
822 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
823 ImageInfo **img_info =
824 (ImageInfo **)(pos < num_list_entries ? image_info->artwork_list :
825 image_info->dynamic_artwork_list);
827 return img_info[list_pos];
830 Bitmap *getBitmapFromImageID(int pos)
833 int num_list_entries = image_info->num_file_list_entries;
834 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
835 ImageInfo **img_info =
836 (ImageInfo **)(pos < num_list_entries ? image_info->artwork_list :
837 image_info->dynamic_artwork_list);
839 return (img_info[list_pos] != NULL ? img_info[list_pos]->bitmap : NULL);
841 ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
843 return (img_info != NULL ? img_info->bitmap : NULL);
847 char *getTokenFromImageID(int graphic)
850 /* !!! this does not work for dynamic artwork (crash!) !!! */
851 struct FileInfo *file_list = (struct FileInfo *)image_info->file_list;
853 return file_list[graphic].token;
855 struct FileInfo *file_list = getImageListEntry(graphic);
857 return (file_list != NULL ? file_list->token : NULL);
861 int getImageIDFromToken(char *token)
863 struct FileInfo *file_list = image_info->file_list;
864 int num_list_entries = image_info->num_file_list_entries;
867 for (i = 0; i < num_list_entries; i++)
868 if (strcmp(file_list[i].token, token) == 0)
874 char *getImageConfigFilename()
876 return getCustomArtworkConfigFilename(image_info->type);
879 int getImageListPropertyMappingSize()
881 return image_info->num_property_mapping_entries;
884 struct PropertyMapping *getImageListPropertyMapping()
886 return image_info->property_mapping;
889 void InitImageList(struct ConfigInfo *config_list, int num_file_list_entries,
890 struct ConfigTypeInfo *config_suffix_list,
891 char **base_prefixes, char **ext1_suffixes,
892 char **ext2_suffixes, char **ext3_suffixes,
893 char **ignore_tokens)
897 image_info = checked_calloc(sizeof(struct ArtworkListInfo));
898 image_info->type = ARTWORK_TYPE_GRAPHICS;
900 /* ---------- initialize file list and suffix lists ---------- */
902 image_info->num_file_list_entries = num_file_list_entries;
903 image_info->num_dynamic_file_list_entries = 0;
905 image_info->file_list =
906 getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
907 num_file_list_entries);
908 image_info->dynamic_file_list = NULL;
910 image_info->num_suffix_list_entries = 0;
911 for (i = 0; config_suffix_list[i].token != NULL; i++)
912 image_info->num_suffix_list_entries++;
914 image_info->suffix_list = config_suffix_list;
916 /* ---------- initialize base prefix and suffixes lists ---------- */
918 image_info->num_base_prefixes = 0;
919 for (i = 0; base_prefixes[i] != NULL; i++)
920 image_info->num_base_prefixes++;
922 image_info->num_ext1_suffixes = 0;
923 for (i = 0; ext1_suffixes[i] != NULL; i++)
924 image_info->num_ext1_suffixes++;
926 image_info->num_ext2_suffixes = 0;
927 for (i = 0; ext2_suffixes[i] != NULL; i++)
928 image_info->num_ext2_suffixes++;
930 image_info->num_ext3_suffixes = 0;
931 for (i = 0; ext3_suffixes[i] != NULL; i++)
932 image_info->num_ext3_suffixes++;
934 image_info->num_ignore_tokens = 0;
935 for (i = 0; ignore_tokens[i] != NULL; i++)
936 image_info->num_ignore_tokens++;
938 image_info->base_prefixes = base_prefixes;
939 image_info->ext1_suffixes = ext1_suffixes;
940 image_info->ext2_suffixes = ext2_suffixes;
941 image_info->ext3_suffixes = ext3_suffixes;
942 image_info->ignore_tokens = ignore_tokens;
944 image_info->num_property_mapping_entries = 0;
946 image_info->property_mapping = NULL;
948 /* ---------- initialize artwork reference and content lists ---------- */
950 image_info->sizeof_artwork_list_entry = sizeof(ImageInfo *);
952 image_info->artwork_list =
953 checked_calloc(num_file_list_entries * sizeof(ImageInfo *));
954 image_info->dynamic_artwork_list = NULL;
956 image_info->content_list = NULL;
958 /* ---------- initialize artwork loading/freeing functions ---------- */
960 image_info->load_artwork = Load_PCX;
961 image_info->free_artwork = FreeImage;
964 void ReloadCustomImages()
967 printf("DEBUG: reloading images '%s' ...\n", artwork.gfx_current_identifier);
970 LoadArtworkConfig(image_info);
971 ReloadCustomArtworkList(image_info);
974 void CreateImageWithSmallImages(int pos)
976 ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
978 if (img_info == NULL || img_info->contains_small_images)
981 CreateBitmapWithSmallBitmaps(img_info->bitmap);
983 img_info->contains_small_images = TRUE;
986 printf("CreateImageWithSmallImages: '%s' done\n", img_info->source_filename);
992 FreeCustomArtworkLists(image_info);