7f8302fcc2605101fdaae9f404367b7272dbe26f
[rocksndiamonds.git] / src / libgame / image.c
1 /***********************************************************
2 * Artsoft Retro-Game Library                               *
3 *----------------------------------------------------------*
4 * (c) 1994-2006 Artsoft Entertainment                      *
5 *               Holger Schemel                             *
6 *               Detmolder Strasse 189                      *
7 *               33604 Bielefeld                            *
8 *               Germany                                    *
9 *               e-mail: info@artsoft.org                   *
10 *----------------------------------------------------------*
11 * image.c                                                  *
12 ***********************************************************/
13
14 #include "image.h"
15 #include "misc.h"
16 #include "setup.h"
17
18
19 struct ImageInfo
20 {
21   char *source_filename;
22   int num_references;
23
24   Bitmap *bitmap;
25
26   int original_width;                   /* original image file width */
27   int original_height;                  /* original image file height */
28
29   boolean contains_small_images;        /* set after adding small images */
30   boolean scaled_up;                    /* set after scaling up */
31 };
32 typedef struct ImageInfo ImageInfo;
33
34 static struct ArtworkListInfo *image_info = NULL;
35
36 #if 1
37 static void *Load_Image(char *filename)
38 #else
39 static void *Load_PCX(char *filename)
40 #endif
41 {
42   ImageInfo *img_info;
43
44 #if 0
45   printf("::: loading PCX file '%s'\n", filename);
46 #endif
47
48   img_info = checked_calloc(sizeof(ImageInfo));
49
50   if ((img_info->bitmap = LoadImage(filename)) == NULL)
51   {
52     Error(ERR_WARN, "cannot load image file '%s': LoadImage() failed: %s",
53           filename, GetError());
54     free(img_info);
55     return NULL;
56   }
57
58   img_info->source_filename = getStringCopy(filename);
59
60   img_info->original_width  = img_info->bitmap->width;
61   img_info->original_height = img_info->bitmap->height;
62
63   img_info->contains_small_images = FALSE;
64   img_info->scaled_up = FALSE;
65
66   return img_info;
67 }
68
69 static void FreeImage(void *ptr)
70 {
71   ImageInfo *image = (ImageInfo *)ptr;
72
73   if (image == NULL)
74     return;
75
76   if (image->bitmap)
77     FreeBitmap(image->bitmap);
78
79   if (image->source_filename)
80     free(image->source_filename);
81
82   free(image);
83 }
84
85 int getImageListSize()
86 {
87   return (image_info->num_file_list_entries +
88           image_info->num_dynamic_file_list_entries);
89 }
90
91 struct FileInfo *getImageListEntryFromImageID(int pos)
92 {
93   int num_list_entries = image_info->num_file_list_entries;
94   int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
95
96   return (pos < num_list_entries ? &image_info->file_list[list_pos] :
97           &image_info->dynamic_file_list[list_pos]);
98 }
99
100 static ImageInfo *getImageInfoEntryFromImageID(int pos)
101 {
102   int num_list_entries = image_info->num_file_list_entries;
103   int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
104   ImageInfo **img_info =
105     (ImageInfo **)(pos < num_list_entries ? image_info->artwork_list :
106                    image_info->dynamic_artwork_list);
107
108   return img_info[list_pos];
109 }
110
111 Bitmap *getBitmapFromImageID(int pos)
112 {
113   ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
114
115   return (img_info != NULL ? img_info->bitmap : NULL);
116 }
117
118 int getOriginalImageWidthFromImageID(int pos)
119 {
120   ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
121
122   return (img_info != NULL ? img_info->original_width : 0);
123 }
124
125 int getOriginalImageHeightFromImageID(int pos)
126 {
127   ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
128
129   return (img_info != NULL ? img_info->original_height : 0);
130 }
131
132 char *getTokenFromImageID(int graphic)
133 {
134   struct FileInfo *file_list = getImageListEntryFromImageID(graphic);
135
136   return (file_list != NULL ? file_list->token : NULL);
137 }
138
139 int getImageIDFromToken(char *token)
140 {
141   struct FileInfo *file_list = image_info->file_list;
142   int num_list_entries = image_info->num_file_list_entries;
143   int i;
144
145   for (i = 0; i < num_list_entries; i++)
146     if (strEqual(file_list[i].token, token))
147       return i;
148
149   return -1;
150 }
151
152 char *getImageConfigFilename()
153 {
154   return getCustomArtworkConfigFilename(image_info->type);
155 }
156
157 int getImageListPropertyMappingSize()
158 {
159   return image_info->num_property_mapping_entries;
160 }
161
162 struct PropertyMapping *getImageListPropertyMapping()
163 {
164   return image_info->property_mapping;
165 }
166
167 void InitImageList(struct ConfigInfo *config_list, int num_file_list_entries,
168                    struct ConfigTypeInfo *config_suffix_list,
169                    char **base_prefixes, char **ext1_suffixes,
170                    char **ext2_suffixes, char **ext3_suffixes,
171                    char **ignore_tokens)
172 {
173   int i;
174
175   image_info = checked_calloc(sizeof(struct ArtworkListInfo));
176   image_info->type = ARTWORK_TYPE_GRAPHICS;
177
178   /* ---------- initialize file list and suffix lists ---------- */
179
180   image_info->num_file_list_entries = num_file_list_entries;
181   image_info->num_dynamic_file_list_entries = 0;
182
183   image_info->file_list =
184     getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
185                               num_file_list_entries);
186   image_info->dynamic_file_list = NULL;
187
188   image_info->num_suffix_list_entries = 0;
189   for (i = 0; config_suffix_list[i].token != NULL; i++)
190     image_info->num_suffix_list_entries++;
191
192   image_info->suffix_list = config_suffix_list;
193
194   /* ---------- initialize base prefix and suffixes lists ---------- */
195
196   image_info->num_base_prefixes = 0;
197   for (i = 0; base_prefixes[i] != NULL; i++)
198     image_info->num_base_prefixes++;
199
200   image_info->num_ext1_suffixes = 0;
201   for (i = 0; ext1_suffixes[i] != NULL; i++)
202     image_info->num_ext1_suffixes++;
203
204   image_info->num_ext2_suffixes = 0;
205   for (i = 0; ext2_suffixes[i] != NULL; i++)
206     image_info->num_ext2_suffixes++;
207
208   image_info->num_ext3_suffixes = 0;
209   for (i = 0; ext3_suffixes[i] != NULL; i++)
210     image_info->num_ext3_suffixes++;
211
212   image_info->num_ignore_tokens = 0;
213   for (i = 0; ignore_tokens[i] != NULL; i++)
214     image_info->num_ignore_tokens++;
215
216   image_info->base_prefixes = base_prefixes;
217   image_info->ext1_suffixes = ext1_suffixes;
218   image_info->ext2_suffixes = ext2_suffixes;
219   image_info->ext3_suffixes = ext3_suffixes;
220   image_info->ignore_tokens = ignore_tokens;
221
222   image_info->num_property_mapping_entries = 0;
223
224   image_info->property_mapping = NULL;
225
226   /* ---------- initialize artwork reference and content lists ---------- */
227
228   image_info->sizeof_artwork_list_entry = sizeof(ImageInfo *);
229
230   image_info->artwork_list =
231     checked_calloc(num_file_list_entries * sizeof(ImageInfo *));
232   image_info->dynamic_artwork_list = NULL;
233
234   image_info->content_list = NULL;
235
236   /* ---------- initialize artwork loading/freeing functions ---------- */
237
238 #if 1
239   image_info->load_artwork = Load_Image;
240 #else
241   image_info->load_artwork = Load_PCX;
242 #endif
243   image_info->free_artwork = FreeImage;
244 }
245
246 void ReloadCustomImages()
247 {
248 #if 0
249   printf("::: reloading images '%s' ...\n", artwork.gfx_current_identifier);
250 #endif
251
252   print_timestamp_init("ReloadCustomImages");
253
254   LoadArtworkConfig(image_info);
255   print_timestamp_time("LoadArtworkConfig");
256
257   ReloadCustomArtworkList(image_info);
258   print_timestamp_time("ReloadCustomArtworkList");
259
260   print_timestamp_done("ReloadCustomImages");
261 }
262
263 void CreateImageWithSmallImages(int pos, int zoom_factor, int tile_size)
264 {
265   ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
266
267   if (img_info == NULL || img_info->contains_small_images)
268     return;
269
270   CreateBitmapWithSmallBitmaps(img_info->bitmap, zoom_factor, tile_size);
271
272   img_info->contains_small_images = TRUE;
273   img_info->scaled_up = TRUE;
274 }
275
276 void ScaleImage(int pos, int zoom_factor)
277 {
278   ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
279
280   if (img_info == NULL || img_info->scaled_up)
281     return;
282
283   if (zoom_factor != 1)
284     ScaleBitmap(img_info->bitmap, zoom_factor);
285
286   img_info->scaled_up = TRUE;
287 }
288
289 void FreeAllImages()
290 {
291   FreeCustomArtworkLists(image_info);
292 }