12 #include "newgrf.h" |
12 #include "newgrf.h" |
13 #include "md5.h" |
13 #include "md5.h" |
14 #include "variables.h" |
14 #include "variables.h" |
15 #include <ctype.h> |
15 #include <ctype.h> |
16 |
16 |
17 #define SPRITE_CACHE_SIZE 1024*1024 |
|
18 |
|
19 #define WANT_NEW_LRU |
|
20 |
|
21 |
|
22 /* These are used in newgrf.c: */ |
|
23 |
|
24 int _skip_sprites = 0; // XXX |
|
25 int _replace_sprites_count[16]; // XXX |
|
26 int _replace_sprites_offset[16]; // XXX |
|
27 |
|
28 const char* _cur_grffile; // XXX |
|
29 int _loading_stage; // XXX |
|
30 int _skip_specials; // XXX |
|
31 uint16 _custom_sprites_base; // XXX |
|
32 |
|
33 |
|
34 typedef struct MD5File { |
17 typedef struct MD5File { |
35 const char * const filename; // filename |
18 const char * const filename; // filename |
36 const md5_byte_t hash[16]; // md5 sum of the file |
19 const md5_byte_t hash[16]; // md5 sum of the file |
37 } MD5File; |
20 } MD5File; |
38 |
21 |
56 _slopes_spriteindexes_2, |
39 _slopes_spriteindexes_2, |
57 _slopes_spriteindexes_3, |
40 _slopes_spriteindexes_3, |
58 }; |
41 }; |
59 |
42 |
60 |
43 |
61 static int LoadGrfFile(const char *filename, int load_index, int file_index) |
44 static uint LoadGrfFile(const char* filename, uint load_index, int file_index) |
62 { |
45 { |
63 int load_index_org = load_index; |
46 uint load_index_org = load_index; |
64 |
47 |
65 FioOpenFile(file_index, filename); |
48 FioOpenFile(file_index, filename); |
66 |
|
67 /* Thou shalt use LoadNewGrfFile() if thou loadeth a GRF file that |
|
68 * might contain some special sprites. */ |
|
69 _skip_specials = 1; |
|
70 _skip_sprites = 0; |
|
71 |
49 |
72 DEBUG(spritecache, 2) ("Reading grf-file ``%s''", filename); |
50 DEBUG(spritecache, 2) ("Reading grf-file ``%s''", filename); |
73 |
51 |
74 while (LoadNextSprite(load_index, file_index)) { |
52 while (LoadNextSprite(load_index, file_index)) { |
75 load_index++; |
53 load_index++; |
80 DEBUG(spritecache, 2) ("Currently %i sprites are loaded", load_index); |
58 DEBUG(spritecache, 2) ("Currently %i sprites are loaded", load_index); |
81 |
59 |
82 return load_index - load_index_org; |
60 return load_index - load_index_org; |
83 } |
61 } |
84 |
62 |
85 static int LoadNewGrfFile(const char *filename, int load_index, int file_index) |
63 |
86 { |
64 static void LoadGrfIndexed(const char* filename, const SpriteID* index_tbl, int file_index) |
87 int i; |
65 { |
|
66 uint start; |
88 |
67 |
89 FioOpenFile(file_index, filename); |
68 FioOpenFile(file_index, filename); |
90 _cur_grffile = filename; |
|
91 _skip_specials = 0; |
|
92 _skip_sprites = 0; |
|
93 |
|
94 DEBUG(spritecache, 2) ("Reading newgrf-file ``%s'' [offset: %u]", |
|
95 filename, load_index); |
|
96 |
|
97 /* Skip the first sprite; we don't care about how many sprites this |
|
98 * does contain; newest TTDPatches and George's longvehicles don't |
|
99 * neither, apparently. */ |
|
100 { |
|
101 int length; |
|
102 byte type; |
|
103 |
|
104 length = FioReadWord(); |
|
105 type = FioReadByte(); |
|
106 |
|
107 if (length == 4 && type == 0xFF) { |
|
108 FioReadDword(); |
|
109 } else { |
|
110 error("Custom .grf has invalid format."); |
|
111 } |
|
112 } |
|
113 |
|
114 for (i = 0; LoadNextSprite(load_index + i, file_index); i++) { |
|
115 if (load_index + i >= MAX_SPRITES) |
|
116 error("Too many sprites (0x%X). Recompile with higher MAX_SPRITES value or remove some custom GRF files.", |
|
117 load_index + i); |
|
118 } |
|
119 |
|
120 /* Clean up. */ |
|
121 _skip_sprites = 0; |
|
122 memset(_replace_sprites_count, 0, sizeof(_replace_sprites_count)); |
|
123 memset(_replace_sprites_offset, 0, sizeof(_replace_sprites_offset)); |
|
124 |
|
125 return i; |
|
126 } |
|
127 |
|
128 static void LoadGrfIndexed(const char *filename, const SpriteID *index_tbl, int file_index) |
|
129 { |
|
130 int start; |
|
131 |
|
132 FioOpenFile(file_index, filename); |
|
133 _skip_specials = 1; |
|
134 _skip_sprites = 0; |
|
135 |
69 |
136 DEBUG(spritecache, 2) ("Reading indexed grf-file ``%s''", filename); |
70 DEBUG(spritecache, 2) ("Reading indexed grf-file ``%s''", filename); |
137 |
71 |
138 for (; (start = *index_tbl++) != 0xffff;) { |
72 for (; (start = *index_tbl++) != 0xffff;) { |
139 int end = *index_tbl++; |
73 uint end = *index_tbl++; |
140 if(start == 0xfffe) { // skip sprites (amount in second var) |
74 |
|
75 if (start == 0xfffe) { // skip sprites (amount in second var) |
141 SkipSprites(end); |
76 SkipSprites(end); |
142 } else { // load sprites and use indexes from start to end |
77 } else { // load sprites and use indexes from start to end |
143 do { |
78 do { |
144 #ifdef NDEBUG |
79 #ifdef NDEBUG |
145 LoadNextSprite(start, file_index); |
80 LoadNextSprite(start, file_index); |
150 } while (++start <= end); |
85 } while (++start <= end); |
151 } |
86 } |
152 } |
87 } |
153 } |
88 } |
154 |
89 |
155 |
|
156 static byte _sprite_page_to_load = 0xFF; |
|
157 |
90 |
158 #define OPENTTD_SPRITES_COUNT 100 |
91 #define OPENTTD_SPRITES_COUNT 100 |
159 static const SpriteID _openttd_grf_indexes[] = { |
92 static const SpriteID _openttd_grf_indexes[] = { |
160 SPR_OPENTTD_BASE + 0, SPR_OPENTTD_BASE + 7, // icons etc |
93 SPR_OPENTTD_BASE + 0, SPR_OPENTTD_BASE + 7, // icons etc |
161 134, 134, // euro symbol medium size |
94 134, 134, // euro symbol medium size |
168 634, 634, // nordic char: Ø |
101 634, 634, // nordic char: Ø |
169 SPR_OPENTTD_BASE+62, SPR_OPENTTD_BASE + OPENTTD_SPRITES_COUNT, // more icons |
102 SPR_OPENTTD_BASE+62, SPR_OPENTTD_BASE + OPENTTD_SPRITES_COUNT, // more icons |
170 0xffff, |
103 0xffff, |
171 }; |
104 }; |
172 |
105 |
173 /* FUNCTIONS FOR CHECKING MD5 SUMS OF GRF FILES */ |
|
174 |
106 |
175 /* Check that the supplied MD5 hash matches that stored for the supplied filename */ |
107 /* Check that the supplied MD5 hash matches that stored for the supplied filename */ |
176 static bool CheckMD5Digest(const MD5File file, md5_byte_t *digest, bool warn) |
108 static bool CheckMD5Digest(const MD5File file, md5_byte_t *digest, bool warn) |
177 { |
109 { |
178 uint i; |
110 uint i; |
267 } else { |
199 } else { |
268 _use_dos_palette = false; |
200 _use_dos_palette = false; |
269 } |
201 } |
270 } |
202 } |
271 |
203 |
|
204 |
|
205 static byte _sprite_page_to_load = 0xFF; |
|
206 |
272 static void LoadSpriteTables(void) |
207 static void LoadSpriteTables(void) |
273 { |
208 { |
274 int load_index = 0; |
209 uint load_index = 0; |
275 uint i; |
210 uint i; |
276 uint j; |
|
277 const FileList *files; // list of grf files to be loaded. Either Windows files or DOS files |
211 const FileList *files; // list of grf files to be loaded. Either Windows files or DOS files |
278 |
|
279 _loading_stage = 1; |
|
280 |
|
281 /* |
|
282 * TODO: |
|
283 * I think we can live entirely without Indexed GRFs, but I have to |
|
284 * invest that further. --octo |
|
285 */ |
|
286 |
212 |
287 files = _use_dos_palette? &files_dos : &files_win; |
213 files = _use_dos_palette? &files_dos : &files_win; |
288 |
214 |
289 for (i = 0; files->basic[i].filename != NULL; i++) { |
215 for (i = 0; files->basic[i].filename != NULL; i++) { |
290 load_index += LoadGrfFile(files->basic[i].filename, load_index, i); |
216 load_index += LoadGrfFile(files->basic[i].filename, load_index, i); |
308 load_index = SPR_CANALS_BASE; |
234 load_index = SPR_CANALS_BASE; |
309 load_index += LoadGrfFile("canalsw.grf", load_index, i++); |
235 load_index += LoadGrfFile("canalsw.grf", load_index, i++); |
310 |
236 |
311 load_index = SPR_OPENTTD_BASE + OPENTTD_SPRITES_COUNT + 1; |
237 load_index = SPR_OPENTTD_BASE + OPENTTD_SPRITES_COUNT + 1; |
312 |
238 |
313 |
239 LoadNewGRF(load_index, i); |
314 /* Load newgrf sprites |
|
315 * in each loading stage, (try to) open each file specified in the config |
|
316 * and load information from it. */ |
|
317 _custom_sprites_base = load_index; |
|
318 for (_loading_stage = 0; _loading_stage < 2; _loading_stage++) { |
|
319 load_index = _custom_sprites_base; |
|
320 for (j = 0; j != lengthof(_newgrf_files) && _newgrf_files[j]; j++) { |
|
321 if (!FiosCheckFileExists(_newgrf_files[j])) { |
|
322 // TODO: usrerror() |
|
323 error("NewGRF file missing: %s", _newgrf_files[j]); |
|
324 } |
|
325 if (_loading_stage == 0) InitNewGRFFile(_newgrf_files[j], load_index); |
|
326 load_index += LoadNewGrfFile(_newgrf_files[j], load_index, i++); |
|
327 DEBUG(spritecache, 2) ("Currently %i sprites are loaded", load_index); |
|
328 } |
|
329 } |
|
330 } |
240 } |
331 |
241 |
332 |
242 |
333 void GfxLoadSprites(void) |
243 void GfxLoadSprites(void) |
334 { |
244 { |