major cleanup of preprocessor hell
[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 static void *Load_Image(char *filename)
35 {
36   ImageInfo *img_info;
37
38   img_info = checked_calloc(sizeof(ImageInfo));
39
40   if ((img_info->bitmap = LoadImage(filename)) == NULL)
41   {
42     Error(ERR_WARN, "cannot load image file '%s': LoadImage() failed: %s",
43           filename, GetError());
44     free(img_info);
45     return NULL;
46   }
47
48   img_info->source_filename = getStringCopy(filename);
49
50   img_info->original_width  = img_info->bitmap->width;
51   img_info->original_height = img_info->bitmap->height;
52
53   img_info->contains_small_images = FALSE;
54   img_info->scaled_up = FALSE;
55
56   return img_info;
57 }
58
59 static void FreeImage(void *ptr)
60 {
61   ImageInfo *image = (ImageInfo *)ptr;
62
63   if (image == NULL)
64     return;
65
66   if (image->bitmap)
67     FreeBitmap(image->bitmap);
68
69   if (image->source_filename)
70     free(image->source_filename);
71
72   free(image);
73 }
74
75 int getImageListSize()
76 {
77   return (image_info->num_file_list_entries +
78           image_info->num_dynamic_file_list_entries);
79 }
80
81 struct FileInfo *getImageListEntryFromImageID(int pos)
82 {
83   int num_list_entries = image_info->num_file_list_entries;
84   int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
85
86   return (pos < num_list_entries ? &image_info->file_list[list_pos] :
87           &image_info->dynamic_file_list[list_pos]);
88 }
89
90 static ImageInfo *getImageInfoEntryFromImageID(int pos)
91 {
92   int num_list_entries = image_info->num_file_list_entries;
93   int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
94   ImageInfo **img_info =
95     (ImageInfo **)(pos < num_list_entries ? image_info->artwork_list :
96                    image_info->dynamic_artwork_list);
97
98   return img_info[list_pos];
99 }
100
101 Bitmap *getBitmapFromImageID(int pos)
102 {
103   ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
104
105   return (img_info != NULL ? img_info->bitmap : NULL);
106 }
107
108 int getOriginalImageWidthFromImageID(int pos)
109 {
110   ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
111
112   return (img_info != NULL ? img_info->original_width : 0);
113 }
114
115 int getOriginalImageHeightFromImageID(int pos)
116 {
117   ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
118
119   return (img_info != NULL ? img_info->original_height : 0);
120 }
121
122 char *getTokenFromImageID(int graphic)
123 {
124   struct FileInfo *file_list = getImageListEntryFromImageID(graphic);
125
126   return (file_list != NULL ? file_list->token : NULL);
127 }
128
129 int getImageIDFromToken(char *token)
130 {
131   struct FileInfo *file_list = image_info->file_list;
132   int num_list_entries = image_info->num_file_list_entries;
133   int i;
134
135   for (i = 0; i < num_list_entries; i++)
136     if (strEqual(file_list[i].token, token))
137       return i;
138
139   return -1;
140 }
141
142 char *getImageConfigFilename()
143 {
144   return getCustomArtworkConfigFilename(image_info->type);
145 }
146
147 int getImageListPropertyMappingSize()
148 {
149   return image_info->num_property_mapping_entries;
150 }
151
152 struct PropertyMapping *getImageListPropertyMapping()
153 {
154   return image_info->property_mapping;
155 }
156
157 void InitImageList(struct ConfigInfo *config_list, int num_file_list_entries,
158                    struct ConfigTypeInfo *config_suffix_list,
159                    char **base_prefixes, char **ext1_suffixes,
160                    char **ext2_suffixes, char **ext3_suffixes,
161                    char **ignore_tokens)
162 {
163   int i;
164
165   image_info = checked_calloc(sizeof(struct ArtworkListInfo));
166   image_info->type = ARTWORK_TYPE_GRAPHICS;
167
168   /* ---------- initialize file list and suffix lists ---------- */
169
170   image_info->num_file_list_entries = num_file_list_entries;
171   image_info->num_dynamic_file_list_entries = 0;
172
173   image_info->file_list =
174     getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
175                               num_file_list_entries);
176   image_info->dynamic_file_list = NULL;
177
178   image_info->num_suffix_list_entries = 0;
179   for (i = 0; config_suffix_list[i].token != NULL; i++)
180     image_info->num_suffix_list_entries++;
181
182   image_info->suffix_list = config_suffix_list;
183
184   /* ---------- initialize base prefix and suffixes lists ---------- */
185
186   image_info->num_base_prefixes = 0;
187   for (i = 0; base_prefixes[i] != NULL; i++)
188     image_info->num_base_prefixes++;
189
190   image_info->num_ext1_suffixes = 0;
191   for (i = 0; ext1_suffixes[i] != NULL; i++)
192     image_info->num_ext1_suffixes++;
193
194   image_info->num_ext2_suffixes = 0;
195   for (i = 0; ext2_suffixes[i] != NULL; i++)
196     image_info->num_ext2_suffixes++;
197
198   image_info->num_ext3_suffixes = 0;
199   for (i = 0; ext3_suffixes[i] != NULL; i++)
200     image_info->num_ext3_suffixes++;
201
202   image_info->num_ignore_tokens = 0;
203   for (i = 0; ignore_tokens[i] != NULL; i++)
204     image_info->num_ignore_tokens++;
205
206   image_info->base_prefixes = base_prefixes;
207   image_info->ext1_suffixes = ext1_suffixes;
208   image_info->ext2_suffixes = ext2_suffixes;
209   image_info->ext3_suffixes = ext3_suffixes;
210   image_info->ignore_tokens = ignore_tokens;
211
212   image_info->num_property_mapping_entries = 0;
213
214   image_info->property_mapping = NULL;
215
216   /* ---------- initialize artwork reference and content lists ---------- */
217
218   image_info->sizeof_artwork_list_entry = sizeof(ImageInfo *);
219
220   image_info->artwork_list =
221     checked_calloc(num_file_list_entries * sizeof(ImageInfo *));
222   image_info->dynamic_artwork_list = NULL;
223
224   image_info->content_list = NULL;
225
226   /* ---------- initialize artwork loading/freeing functions ---------- */
227
228   image_info->load_artwork = Load_Image;
229   image_info->free_artwork = FreeImage;
230 }
231
232 void ReloadCustomImages()
233 {
234   print_timestamp_init("ReloadCustomImages");
235
236   LoadArtworkConfig(image_info);
237   print_timestamp_time("LoadArtworkConfig");
238
239   ReloadCustomArtworkList(image_info);
240   print_timestamp_time("ReloadCustomArtworkList");
241
242   print_timestamp_done("ReloadCustomImages");
243 }
244
245 void CreateImageWithSmallImages(int pos, int zoom_factor, int tile_size)
246 {
247   ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
248
249   if (img_info == NULL || img_info->contains_small_images)
250     return;
251
252   CreateBitmapWithSmallBitmaps(img_info->bitmap, zoom_factor, tile_size);
253
254   img_info->contains_small_images = TRUE;
255   img_info->scaled_up = TRUE;
256 }
257
258 void ScaleImage(int pos, int zoom_factor)
259 {
260   ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
261
262   if (img_info == NULL || img_info->scaled_up)
263     return;
264
265   if (zoom_factor != 1)
266     ScaleBitmap(img_info->bitmap, zoom_factor);
267
268   img_info->scaled_up = TRUE;
269 }
270
271 void FreeAllImages()
272 {
273   FreeCustomArtworkLists(image_info);
274 }