1 // ============================================================================
2 // Artsoft Retro-Game Library
3 // ----------------------------------------------------------------------------
4 // (c) 1995-2014 by Artsoft Entertainment
7 // http://www.artsoft.org/
8 // ----------------------------------------------------------------------------
10 // ============================================================================
19 char *source_filename;
22 Bitmap *bitmaps[NUM_IMG_BITMAP_POINTERS];
24 int original_width; /* original image file width */
25 int original_height; /* original image file height */
27 boolean contains_small_images; /* set after adding small images */
28 boolean contains_textures; /* set after adding GPU textures */
29 boolean scaled_up; /* set after scaling up */
31 int conf_tile_size; /* tile size as defined in config */
32 int game_tile_size; /* tile size as resized for game */
34 char *leveldir; /* level set when image was loaded */
36 typedef struct ImageInfo ImageInfo;
38 static struct ArtworkListInfo *image_info = NULL;
40 static void *Load_Image(char *filename)
42 ImageInfo *img_info = checked_calloc(sizeof(ImageInfo));
44 if ((img_info->bitmaps[IMG_BITMAP_STANDARD] = LoadImage(filename)) == NULL)
46 Error(ERR_WARN, "cannot load image file '%s': LoadImage() failed: %s",
47 filename, GetError());
54 img_info->source_filename = getStringCopy(filename);
56 img_info->original_width = img_info->bitmaps[IMG_BITMAP_STANDARD]->width;
57 img_info->original_height = img_info->bitmaps[IMG_BITMAP_STANDARD]->height;
59 img_info->contains_small_images = FALSE;
60 img_info->contains_textures = FALSE;
61 img_info->scaled_up = FALSE;
63 img_info->conf_tile_size = 0; // will be set later
64 img_info->game_tile_size = 0; // will be set later
66 img_info->leveldir = NULL; // will be set later
71 static void FreeImage(void *ptr)
73 ImageInfo *image = (ImageInfo *)ptr;
79 for (i = 0; i < NUM_IMG_BITMAPS; i++)
80 if (image->bitmaps[i])
81 FreeBitmap(image->bitmaps[i]);
83 if (image->source_filename)
84 free(image->source_filename);
89 int getImageListSize()
91 return (image_info->num_file_list_entries +
92 image_info->num_dynamic_file_list_entries);
95 struct FileInfo *getImageListEntryFromImageID(int pos)
97 int num_list_entries = image_info->num_file_list_entries;
98 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
100 return (pos < num_list_entries ? &image_info->file_list[list_pos] :
101 &image_info->dynamic_file_list[list_pos]);
104 static ImageInfo *getImageInfoEntryFromImageID(int pos)
106 int num_list_entries = image_info->num_file_list_entries;
107 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
108 ImageInfo **img_info =
109 (ImageInfo **)(pos < num_list_entries ? image_info->artwork_list :
110 image_info->dynamic_artwork_list);
112 return img_info[list_pos];
115 Bitmap **getBitmapsFromImageID(int pos)
117 ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
119 return (img_info != NULL ? img_info->bitmaps : NULL);
122 int getOriginalImageWidthFromImageID(int pos)
124 ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
126 return (img_info != NULL ? img_info->original_width : 0);
129 int getOriginalImageHeightFromImageID(int pos)
131 ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
133 return (img_info != NULL ? img_info->original_height : 0);
136 char *getTokenFromImageID(int graphic)
138 struct FileInfo *file_list = getImageListEntryFromImageID(graphic);
140 return (file_list != NULL ? file_list->token : NULL);
143 char *getFilenameFromImageID(int graphic)
145 struct FileInfo *file_list = getImageListEntryFromImageID(graphic);
147 return (file_list != NULL ? file_list->filename : NULL);
150 int getImageIDFromToken(char *token)
152 struct FileInfo *file_list = image_info->file_list;
153 int num_list_entries = image_info->num_file_list_entries;
156 for (i = 0; i < num_list_entries; i++)
157 if (strEqual(file_list[i].token, token))
163 char *getImageConfigFilename()
165 return getCustomArtworkConfigFilename(image_info->type);
168 int getImageListPropertyMappingSize()
170 return image_info->num_property_mapping_entries;
173 struct PropertyMapping *getImageListPropertyMapping()
175 return image_info->property_mapping;
178 void InitImageList(struct ConfigInfo *config_list, int num_file_list_entries,
179 struct ConfigTypeInfo *config_suffix_list,
180 char **base_prefixes, char **ext1_suffixes,
181 char **ext2_suffixes, char **ext3_suffixes,
182 char **ignore_tokens)
186 image_info = checked_calloc(sizeof(struct ArtworkListInfo));
187 image_info->type = ARTWORK_TYPE_GRAPHICS;
189 /* ---------- initialize file list and suffix lists ---------- */
191 image_info->num_file_list_entries = num_file_list_entries;
192 image_info->num_dynamic_file_list_entries = 0;
194 image_info->file_list =
195 getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
196 num_file_list_entries);
197 image_info->dynamic_file_list = NULL;
199 image_info->num_suffix_list_entries = 0;
200 for (i = 0; config_suffix_list[i].token != NULL; i++)
201 image_info->num_suffix_list_entries++;
203 image_info->suffix_list = config_suffix_list;
205 /* ---------- initialize base prefix and suffixes lists ---------- */
207 image_info->num_base_prefixes = 0;
208 for (i = 0; base_prefixes[i] != NULL; i++)
209 image_info->num_base_prefixes++;
211 image_info->num_ext1_suffixes = 0;
212 for (i = 0; ext1_suffixes[i] != NULL; i++)
213 image_info->num_ext1_suffixes++;
215 image_info->num_ext2_suffixes = 0;
216 for (i = 0; ext2_suffixes[i] != NULL; i++)
217 image_info->num_ext2_suffixes++;
219 image_info->num_ext3_suffixes = 0;
220 for (i = 0; ext3_suffixes[i] != NULL; i++)
221 image_info->num_ext3_suffixes++;
223 image_info->num_ignore_tokens = 0;
224 for (i = 0; ignore_tokens[i] != NULL; i++)
225 image_info->num_ignore_tokens++;
227 image_info->base_prefixes = base_prefixes;
228 image_info->ext1_suffixes = ext1_suffixes;
229 image_info->ext2_suffixes = ext2_suffixes;
230 image_info->ext3_suffixes = ext3_suffixes;
231 image_info->ignore_tokens = ignore_tokens;
233 image_info->num_property_mapping_entries = 0;
235 image_info->property_mapping = NULL;
237 /* ---------- initialize artwork reference and content lists ---------- */
239 image_info->sizeof_artwork_list_entry = sizeof(ImageInfo *);
241 image_info->artwork_list =
242 checked_calloc(num_file_list_entries * sizeof(ImageInfo *));
243 image_info->dynamic_artwork_list = NULL;
245 image_info->content_list = NULL;
247 /* ---------- initialize artwork loading/freeing functions ---------- */
249 image_info->load_artwork = Load_Image;
250 image_info->free_artwork = FreeImage;
253 void ReloadCustomImages()
255 print_timestamp_init("ReloadCustomImages");
257 LoadArtworkConfig(image_info);
258 print_timestamp_time("LoadArtworkConfig");
260 ReloadCustomArtworkList(image_info);
261 print_timestamp_time("ReloadCustomArtworkList");
263 print_timestamp_done("ReloadCustomImages");
266 static boolean CheckIfImageContainsSmallImages(ImageInfo *img_info,
269 if (!img_info->contains_small_images)
272 // at this point, small images already exist for this image;
273 // now do some checks that may require re-creating small (or in-game) images
277 // check if the configured tile size for an already loaded image has changed
278 // from one level set to another; this should usually not happen, but if a
279 // custom artwork set redefines classic (or default) graphics with wrong tile
280 // size (by mistake or by intention), it will be corrected to its original
281 // tile size here by forcing complete re-creation of all small images again
283 if (!strEqual(img_info->leveldir, leveldir_current->identifier) &&
284 img_info->conf_tile_size != tile_size)
286 int bitmap_nr = GET_BITMAP_ID_FROM_TILESIZE(img_info->conf_tile_size);
289 // free all calculated, resized bitmaps, but keep last configured size
290 for (i = 0; i < NUM_IMG_BITMAPS; i++)
295 if (img_info->bitmaps[i])
297 FreeBitmap(img_info->bitmaps[i]);
299 img_info->bitmaps[i] = NULL;
303 // re-create small bitmaps from last configured size as new default size
304 if (bitmap_nr != IMG_BITMAP_STANDARD)
306 img_info->bitmaps[IMG_BITMAP_STANDARD] = img_info->bitmaps[bitmap_nr];
307 img_info->bitmaps[bitmap_nr] = NULL;
310 img_info->contains_small_images = FALSE;
315 // special case 1 (continued):
317 // if different tile sizes are used in same image file (usually by mistake,
318 // like forgetting option ".tile_size" for one or more graphic definitions),
319 // make sure to use only the first tile size that is processed for this image
320 // (and ignore all subsequent, potentially different tile size definitions
321 // for this image within the current level set by disabling the above check)
323 setString(&img_info->leveldir, leveldir_current->identifier);
327 // graphic config setting "game.tile_size" has changed since last level set;
328 // this may require resizing image to new size required for in-game graphics
330 if (img_info->game_tile_size != gfx.game_tile_size)
332 ReCreateGameTileSizeBitmap(img_info->bitmaps);
334 img_info->game_tile_size = gfx.game_tile_size;
340 void CreateImageWithSmallImages(int pos, int zoom_factor, int tile_size)
342 ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
344 if (img_info == NULL)
347 if (CheckIfImageContainsSmallImages(img_info, tile_size))
350 CreateBitmapWithSmallBitmaps(img_info->bitmaps, zoom_factor, tile_size);
352 img_info->contains_small_images = TRUE;
353 img_info->scaled_up = TRUE; // scaling was also done here
355 img_info->conf_tile_size = tile_size;
356 img_info->game_tile_size = gfx.game_tile_size;
358 setString(&img_info->leveldir, leveldir_current->identifier);
361 void CreateImageTextures(int pos)
363 ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
365 if (img_info == NULL || img_info->contains_textures)
368 CreateBitmapTextures(img_info->bitmaps);
370 img_info->contains_textures = TRUE;
373 void FreeImageTextures(int pos)
375 ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
377 if (img_info == NULL || !img_info->contains_textures)
380 FreeBitmapTextures(img_info->bitmaps);
382 img_info->contains_textures = FALSE;
385 void FreeAllImageTextures()
387 int num_images = getImageListSize();
390 for (i = 0; i < num_images; i++)
391 FreeImageTextures(i);
394 void ScaleImage(int pos, int zoom_factor)
396 ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
398 if (img_info == NULL || img_info->scaled_up)
401 if (zoom_factor != 1)
402 ScaleBitmap(img_info->bitmaps, zoom_factor);
404 img_info->scaled_up = TRUE;
409 FreeCustomArtworkLists(image_info);