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