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 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 /* adjust source image size to integer multiple of destination image size */
590 src_width = dst_width * zoom_factor;
591 src_height = dst_height * zoom_factor;
593 /* copy source pixmap to temporary image */
594 src_ximage = XGetImage(display, src_pixmap, 0, 0, src_width, src_height,
597 bits_per_pixel = src_ximage->bits_per_pixel;
598 bytes_per_pixel = (bits_per_pixel + 7) / 8;
600 dst_ximage = XCreateImage(display, visual, src_ximage->depth, ZPixmap,
601 0, NULL, dst_width, dst_height,
602 8, dst_width * bytes_per_pixel);
604 checked_malloc(dst_width * dst_height * bytes_per_pixel);
605 dst_ximage->byte_order = src_ximage->byte_order;
607 src_ptr = (byte *)src_ximage->data;
608 dst_ptr = (byte *)dst_ximage->data;
610 col_skip = (zoom_factor - 1) * bytes_per_pixel;
611 row_skip = col_skip * src_width;
613 /* scale image down by scaling factor 'zoom_factor' */
614 for (y = 0; y < src_height; y += zoom_factor, src_ptr += row_skip)
615 for (x = 0; x < src_width; x += zoom_factor, src_ptr += col_skip)
616 for (i = 0; i < bytes_per_pixel; i++)
617 *dst_ptr++ = *src_ptr++;
619 /* copy scaled image to destination pixmap */
620 XPutImage(display, dst_pixmap, gc, dst_ximage, 0, 0, 0, 0,
621 dst_width, dst_height);
623 /* free temporary images */
624 X11DestroyImage(src_ximage);
625 X11DestroyImage(dst_ximage);
628 void freeXImage(Image *image, XImageInfo *ximageinfo)
630 if (ximageinfo->index != NULL && ximageinfo->no > 0)
631 XFreeColors(ximageinfo->display, ximageinfo->cmap, ximageinfo->index,
633 /* this ^^^^^^^^^^^^^^ is wrong, because the used color cells
634 * are somewhere between 0 and MAX_COLORS; there are indeed 'ximageinfo->no'
635 * used color cells, but they are not at array position 0 - 'ximageinfo->no'
641 int Read_PCX_to_Pixmap(Display *display, Window window, GC gc, char *filename,
642 Pixmap *pixmap, Pixmap *pixmap_mask)
645 XImageInfo *ximageinfo;
651 debug_print_timestamp(2, NULL); /* initialize timestamp function */
654 /* read the graphic file in PCX format to image structure */
655 if ((image = Read_PCX_to_Image(filename)) == NULL)
659 printf("%s:\n", filename);
660 debug_print_timestamp(2, " READING PCX FILE TO IMAGE: ");
663 screen = DefaultScreen(display);
664 visual = DefaultVisual(display, screen);
665 depth = DefaultDepth(display, screen);
667 /* convert image structure to X11 Pixmap */
668 if (!(ximageinfo = Image_to_Pixmap(display, screen, visual,
669 window, gc, depth, image)))
673 return PCX_OtherError;
676 /* if a private colormap has been created, install it */
677 if (ximageinfo->cmap != DefaultColormap(display, screen))
678 XSetWindowColormap(display, window, ximageinfo->cmap);
681 debug_print_timestamp(2, " CONVERTING IMAGE TO PIXMAP:");
684 /* create clip mask for the image */
685 ximageinfo->pixmap_mask = Image_to_Mask(image, display, window);
688 debug_print_timestamp(2, " CONVERTING IMAGE TO MASK: ");
691 *pixmap = ximageinfo->pixmap;
692 *pixmap_mask = ximageinfo->pixmap_mask;
694 /* free generic image and ximageinfo after native Pixmap has been created */
701 #endif /* PLATFORM_UNIX */
702 #endif /* TARGET_X11 */
705 /* ========================================================================= */
706 /* PLATFORM INDEPENDENT IMAGE FUNCTIONS */
707 /* ========================================================================= */
711 char *source_filename;
715 boolean contains_small_images;
717 typedef struct ImageInfo ImageInfo;
719 static struct ArtworkListInfo *image_info = NULL;
721 static void *Load_PCX(char *filename)
726 printf("loading PCX file '%s'\n", filename);
729 img_info = checked_calloc(sizeof(ImageInfo));
731 if ((img_info->bitmap = LoadImage(filename)) == NULL)
733 Error(ERR_WARN, "cannot load image file '%s': LoadImage() failed: %s",
734 filename, GetError());
739 img_info->source_filename = getStringCopy(filename);
741 img_info->contains_small_images = FALSE;
746 static void FreeImage(void *ptr)
748 ImageInfo *image = (ImageInfo *)ptr;
754 FreeBitmap(image->bitmap);
756 if (image->source_filename)
757 free(image->source_filename);
762 int getImageListSize()
764 return (image_info->num_file_list_entries +
765 image_info->num_dynamic_file_list_entries);
768 struct FileInfo *getImageListEntry(int pos)
770 int num_list_entries = image_info->num_file_list_entries;
771 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
773 return (pos < num_list_entries ? &image_info->file_list[list_pos] :
774 &image_info->dynamic_file_list[list_pos]);
777 static ImageInfo *getImageInfoEntryFromImageID(int pos)
779 int num_list_entries = image_info->num_file_list_entries;
780 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
781 ImageInfo **img_info =
782 (ImageInfo **)(pos < num_list_entries ? image_info->artwork_list :
783 image_info->dynamic_artwork_list);
785 return img_info[list_pos];
788 Bitmap *getBitmapFromImageID(int pos)
791 int num_list_entries = image_info->num_file_list_entries;
792 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
793 ImageInfo **img_info =
794 (ImageInfo **)(pos < num_list_entries ? image_info->artwork_list :
795 image_info->dynamic_artwork_list);
797 return (img_info[list_pos] != NULL ? img_info[list_pos]->bitmap : NULL);
799 ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
801 return (img_info != NULL ? img_info->bitmap : NULL);
805 char *getTokenFromImageID(int graphic)
808 /* !!! this does not work for dynamic artwork (crash!) !!! */
809 struct FileInfo *file_list = (struct FileInfo *)image_info->file_list;
811 return file_list[graphic].token;
813 struct FileInfo *file_list = getImageListEntry(graphic);
815 return (file_list != NULL ? file_list->token : NULL);
819 int getImageIDFromToken(char *token)
821 struct FileInfo *file_list = image_info->file_list;
822 int num_list_entries = image_info->num_file_list_entries;
825 for (i = 0; i < num_list_entries; i++)
826 if (strcmp(file_list[i].token, token) == 0)
832 char *getImageConfigFilename()
834 return getCustomArtworkConfigFilename(image_info->type);
837 int getImageListPropertyMappingSize()
839 return image_info->num_property_mapping_entries;
842 struct PropertyMapping *getImageListPropertyMapping()
844 return image_info->property_mapping;
847 void InitImageList(struct ConfigInfo *config_list, int num_file_list_entries,
848 struct ConfigTypeInfo *config_suffix_list,
849 char **base_prefixes, char **ext1_suffixes,
850 char **ext2_suffixes, char **ext3_suffixes,
851 char **ignore_tokens)
855 image_info = checked_calloc(sizeof(struct ArtworkListInfo));
856 image_info->type = ARTWORK_TYPE_GRAPHICS;
858 /* ---------- initialize file list and suffix lists ---------- */
860 image_info->num_file_list_entries = num_file_list_entries;
861 image_info->num_dynamic_file_list_entries = 0;
863 image_info->file_list =
864 getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
865 num_file_list_entries);
866 image_info->dynamic_file_list = NULL;
868 image_info->num_suffix_list_entries = 0;
869 for (i = 0; config_suffix_list[i].token != NULL; i++)
870 image_info->num_suffix_list_entries++;
872 image_info->suffix_list = config_suffix_list;
874 /* ---------- initialize base prefix and suffixes lists ---------- */
876 image_info->num_base_prefixes = 0;
877 for (i = 0; base_prefixes[i] != NULL; i++)
878 image_info->num_base_prefixes++;
880 image_info->num_ext1_suffixes = 0;
881 for (i = 0; ext1_suffixes[i] != NULL; i++)
882 image_info->num_ext1_suffixes++;
884 image_info->num_ext2_suffixes = 0;
885 for (i = 0; ext2_suffixes[i] != NULL; i++)
886 image_info->num_ext2_suffixes++;
888 image_info->num_ext3_suffixes = 0;
889 for (i = 0; ext3_suffixes[i] != NULL; i++)
890 image_info->num_ext3_suffixes++;
892 image_info->num_ignore_tokens = 0;
893 for (i = 0; ignore_tokens[i] != NULL; i++)
894 image_info->num_ignore_tokens++;
896 image_info->base_prefixes = base_prefixes;
897 image_info->ext1_suffixes = ext1_suffixes;
898 image_info->ext2_suffixes = ext2_suffixes;
899 image_info->ext3_suffixes = ext3_suffixes;
900 image_info->ignore_tokens = ignore_tokens;
902 image_info->num_property_mapping_entries = 0;
904 image_info->property_mapping = NULL;
906 /* ---------- initialize artwork reference and content lists ---------- */
908 image_info->sizeof_artwork_list_entry = sizeof(ImageInfo *);
910 image_info->artwork_list =
911 checked_calloc(num_file_list_entries * sizeof(ImageInfo *));
912 image_info->dynamic_artwork_list = NULL;
914 image_info->content_list = NULL;
916 /* ---------- initialize artwork loading/freeing functions ---------- */
918 image_info->load_artwork = Load_PCX;
919 image_info->free_artwork = FreeImage;
922 void ReloadCustomImages()
925 printf("DEBUG: reloading images '%s' ...\n", artwork.gfx_current_identifier);
928 LoadArtworkConfig(image_info);
929 ReloadCustomArtworkList(image_info);
932 void CreateImageWithSmallImages(int pos)
934 ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
936 if (img_info == NULL || img_info->contains_small_images)
939 CreateBitmapWithSmallBitmaps(img_info->bitmap);
941 img_info->contains_small_images = TRUE;
944 printf("CreateImageWithSmallImages: '%s' done\n", img_info->source_filename);
950 FreeCustomArtworkLists(image_info);