Mercurial > hg > dmlib
annotate dmres.c @ 27:21c14afbf63d
Modularize the resource system a bit.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 29 Sep 2012 06:00:26 +0300 |
parents | 2f463a59d732 |
children | e9f562f07cb0 |
rev | line source |
---|---|
0 | 1 /* |
2 * dmlib | |
3 * -- Resource management | |
4 * Programmed and designed by Matti 'ccr' Hamalainen | |
5 * (C) Copyright 2003-2012 Tecnic Software productions (TNSP) | |
6 */ | |
7 #include "dmres.h" | |
8 #include <time.h> | |
9 | |
10 #if !defined(DMRES_PACKFS) && !defined(DMRES_STDIO) | |
11 #error At least one of DMRES_PACKFS, DMRES_STDIO must be defined. | |
12 #endif | |
13 | |
14 #define DMRES_LOCK(x) dmMutexLock(dfResourcesMutex) | |
15 #define DMRES_UNLOCK(x) dmMutexUnlock(dfResourcesMutex) | |
16 | |
17 | |
18 /* Global variables | |
19 */ | |
20 static BOOL dfResInitialized = FALSE; | |
21 static int dfResFlags = 0; | |
22 static char * dfResPath = NULL; | |
23 DMResource * dfResources = NULL; | |
24 DMMutex * dfResourcesMutex = NULL; | |
25 | |
26 | |
27 #ifdef DMRES_PACKFS | |
28 static DMPackFile *dfResPackFile = NULL; | |
29 static char * dfResPackFilename = NULL; | |
30 #endif | |
31 | |
32 | |
33 DMResource *dmres_new(const char *filename, int flags, size_t size) | |
34 { | |
27
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
35 DMResource *node = dmMalloc0(sizeof(DMResource)); |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
36 if (node == NULL) |
0 | 37 return NULL; |
38 | |
27
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
39 node->filename = dm_strdup(filename); |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
40 node->flags = flags; |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
41 node->dataSize = size; |
0 | 42 |
27
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
43 return node; |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
44 } |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
45 |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
46 |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
47 void dmres_free_res_data(DMResource *node) |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
48 { |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
49 if (node->rdata != NULL && |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
50 node->rops != NULL && |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
51 node->rops->free != NULL) |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
52 { |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
53 node->rops->free(node); |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
54 } |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
55 |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
56 node->rdata = NULL; |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
57 node->flags &= !DMF_LOADED_RES; |
0 | 58 } |
59 | |
60 | |
27
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
61 void dmres_free_raw_data(DMResource *node) |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
62 { |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
63 dmFree(node->data); |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
64 node->data = NULL; |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
65 node->flags &= !DMF_LOADED_RAW; |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
66 } |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
67 |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
68 |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
69 void dmres_purge_raw_data(DMResource *node) |
0 | 70 { |
27
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
71 if ((node->flags & DMF_PRELOAD_RAW) == 0 && |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
72 (node->flags & DMF_LOADED_RAW) && |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
73 node->data != NULL) |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
74 dmres_free_raw_data(node); |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
75 } |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
76 |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
77 |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
78 void dmres_free(DMResource *node) |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
79 { |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
80 if (node != NULL) |
0 | 81 { |
27
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
82 dmres_free_res_data(node); |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
83 dmres_free_raw_data(node); |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
84 dmFree(node->filename); |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
85 dmFree(node); |
0 | 86 } |
87 } | |
88 | |
89 | |
90 void dmres_insert(DMResource * node) | |
91 { | |
92 if (dfResources != NULL) | |
93 { | |
94 node->prev = dfResources->prev; | |
95 dfResources->prev->next = node; | |
96 dfResources->prev = node; | |
97 } | |
98 else | |
99 { | |
100 dfResources = node->prev = node; | |
101 } | |
102 | |
103 node->next = NULL; | |
104 } | |
105 | |
106 | |
107 void dmres_delete(DMResource * node) | |
108 { | |
109 if (node->prev) | |
110 node->prev->next = node->next; | |
111 | |
112 if (node->next) | |
113 node->next->prev = node->prev; | |
114 else | |
115 dfResources->prev = node->prev; | |
116 | |
117 node->prev = node->next = NULL; | |
118 } | |
119 | |
120 | |
121 DMResource * dmres_find(const char *filename) | |
122 { | |
123 DMResource *node, *found = NULL; | |
124 | |
125 DMRES_LOCK(); | |
126 | |
127 for (node = dfResources; node != NULL; node = node->next) | |
128 { | |
129 if (strcmp(node->filename, filename) == 0) | |
130 { | |
131 found = node; | |
132 break; | |
133 } | |
134 } | |
135 | |
136 DMRES_UNLOCK(); | |
137 | |
138 return found; | |
139 } | |
140 | |
141 | |
142 #ifdef DMRES_STDIO | |
143 /* Basic stdio file routines | |
144 */ | |
145 static int dm_stdio_fopen(DMResource *handle) | |
146 { | |
147 char *rfilename = dm_strdup_printf("%s%s", DMRES_DATA_PATH, handle->filename); | |
148 if (rfilename == NULL) | |
149 return DMERR_MALLOC; | |
150 | |
151 handle->fh = fopen(rfilename, "rb"); | |
152 dmFree(rfilename); | |
153 | |
154 handle->error = dmGetErrno(); | |
155 return (handle->fh != NULL) ? DMERR_OK : DMERR_FOPEN; | |
156 } | |
157 | |
158 | |
159 static void dm_stdio_fclose(DMResource * f) | |
160 { | |
161 if (f->fh != NULL) | |
162 { | |
163 fclose(f->fh); | |
164 f->fh = NULL; | |
165 } | |
166 } | |
167 | |
168 | |
169 static int dm_stdio_ferror(DMResource * f) | |
170 { | |
171 return f->error; | |
172 } | |
173 | |
174 | |
175 static int dm_stdio_fseek(DMResource *f, const off_t pos, const int whence) | |
176 { | |
177 int ret = fseek(f->fh, pos, whence); | |
178 f->error = dmGetErrno(); | |
179 return ret; | |
180 } | |
181 | |
182 | |
183 static off_t dm_stdio_fsize(DMResource *f) | |
184 { | |
185 off_t savePos, fileSize; | |
186 | |
187 // Check if the size is cached | |
188 if (f->dataSize != 0) | |
189 return f->dataSize; | |
190 | |
191 // Get file size | |
192 savePos = ftell(f->fh); | |
193 if (fseek(f->fh, 0L, SEEK_END) != 0) | |
194 { | |
195 f->error = dmGetErrno(); | |
196 return -1; | |
197 } | |
198 | |
199 fileSize = ftell(f->fh); | |
200 if (fseek(f->fh, savePos, SEEK_SET) != 0) | |
201 { | |
202 f->error = dmGetErrno(); | |
203 return -1; | |
204 } | |
205 | |
206 f->dataSize = fileSize; | |
207 return fileSize; | |
208 } | |
209 | |
210 | |
211 static off_t dm_stdio_ftell(DMResource * f) | |
212 { | |
213 return ftell(f->fh); | |
214 } | |
215 | |
216 | |
217 static BOOL dm_stdio_feof(DMResource * f) | |
218 { | |
219 return feof(f->fh); | |
220 } | |
221 | |
222 | |
223 static int dm_stdio_fgetc(DMResource * f) | |
224 { | |
225 int ret = fgetc(f->fh); | |
226 f->error = dmGetErrno(); | |
227 return ret; | |
228 } | |
229 | |
230 | |
231 static size_t dm_stdio_fread(void *ptr, size_t size, size_t nmemb, DMResource * f) | |
232 { | |
233 size_t ret = fread(ptr, size, nmemb, f->fh); | |
234 f->error = dmGetErrno(); | |
235 return ret; | |
236 } | |
237 | |
238 | |
239 static int dm_stdio_preload(DMResource *handle) | |
240 { | |
241 int ret = dm_stdio_fopen(handle); | |
242 if (ret != DMERR_OK) | |
243 return ret; | |
244 | |
245 dm_stdio_fsize(handle); | |
246 | |
247 handle->data = dmMalloc(handle->dataSize); | |
248 if (handle->data == NULL) | |
249 return DMERR_MALLOC; | |
250 | |
251 if (dm_stdio_fread(handle->data, sizeof(Uint8), handle->dataSize, handle) != handle->dataSize) | |
252 return DMERR_FREAD; | |
253 | |
254 return DMERR_OK; | |
255 } | |
256 | |
257 | |
258 DMResourceOps dfStdioFileOps = | |
259 { | |
260 dm_stdio_ferror, | |
261 dm_stdio_fseek, | |
262 dm_stdio_fsize, | |
263 dm_stdio_ftell, | |
264 dm_stdio_feof, | |
265 dm_stdio_fgetc, | |
266 dm_stdio_fread, | |
267 | |
268 dm_stdio_fopen, | |
269 dm_stdio_fclose, | |
270 dm_stdio_preload | |
271 }; | |
272 | |
273 DMResourceOps dfStdioFHOps = | |
274 { | |
275 dm_stdio_ferror, | |
276 dm_stdio_fseek, | |
277 dm_stdio_fsize, | |
278 dm_stdio_ftell, | |
279 dm_stdio_feof, | |
280 dm_stdio_fgetc, | |
281 dm_stdio_fread, | |
282 | |
283 NULL, | |
284 NULL, | |
285 NULL | |
286 }; | |
287 #endif | |
288 | |
289 | |
290 // Some mingw/windows headers define these as macros, which is bad for us | |
291 #ifdef __WIN32 | |
292 #undef ferror | |
293 #undef feof | |
294 #endif | |
295 | |
296 | |
297 /* | |
298 * PACK file routines | |
299 */ | |
300 #ifdef DMRES_PACKFS | |
301 static int dm_pack_preload(DMResource *handle) | |
302 { | |
303 DMPackEntry *node; | |
304 int res = DMERR_OK, cres, cdataLeft; | |
305 z_stream cstream; | |
306 Uint8 * cbuffer = NULL; | |
307 | |
308 // Search PACK nodelist for file | |
309 if ((node = dm_pack_find(dfResPackFile->entries, handle->filename)) == NULL) | |
310 { | |
311 dmError("Entry '%s' not found in PACK file.\n", handle->filename); | |
312 res = DMERR_NOT_FOUND; | |
313 goto error; | |
314 } | |
315 | |
316 // Seek to entry | |
317 if (fseek(dfResPackFile->file, node->offset, SEEK_SET) == -1) | |
318 { | |
319 dmError("Could not seek node position in PACK file.\n"); | |
320 res = DMERR_FSEEK; | |
321 goto error; | |
322 } | |
323 | |
324 // Allocate a structures and buffers | |
325 cbuffer = (Uint8 *) dmMalloc(DPACK_TMPSIZE); | |
326 if (cbuffer == NULL) | |
327 { | |
328 res = DMERR_MALLOC; | |
329 goto error; | |
330 } | |
331 | |
332 // Initialize fields | |
333 handle->dataOffset = 0; | |
334 handle->dataSize = node->size; | |
335 handle->data = (Uint8 *) dmMalloc(node->size); | |
336 if (handle->data == NULL) | |
337 { | |
338 res = DMERR_MALLOC; | |
339 goto error; | |
340 } | |
341 | |
342 // Initialize decompression | |
343 cstream.zalloc = (alloc_func) Z_NULL; | |
344 cstream.zfree = (free_func) Z_NULL; | |
345 cstream.opaque = (voidpf) Z_NULL; | |
346 cstream.next_out = handle->data; | |
347 cstream.avail_out = handle->dataSize; | |
348 cdataLeft = node->length; | |
349 cres = inflateInit(&(cstream)); | |
350 if (cres != Z_OK) | |
351 { | |
352 dmError("Could not initialize zlib stream inflation.\n"); | |
353 res = DMERR_INIT_FAIL; | |
354 goto error; | |
355 } | |
356 | |
357 // Uncompress the data | |
358 while (cdataLeft > 0 && | |
359 cstream.avail_out > 0 && cres == Z_OK) | |
360 { | |
361 cstream.avail_in = fread( | |
362 cbuffer, sizeof(Uint8), | |
363 (cdataLeft >= DPACK_TMPSIZE) ? DPACK_TMPSIZE : cdataLeft, | |
364 dfResPackFile->file); | |
365 | |
366 cdataLeft -= cstream.avail_in; | |
367 cstream.next_in = cbuffer; | |
368 cres = inflate(&cstream, Z_FULL_FLUSH); | |
369 } | |
370 | |
371 // Cleanup | |
372 inflateEnd(&(cstream)); | |
373 | |
374 error: | |
375 dmFree(cbuffer); | |
376 return res; | |
377 } | |
378 #endif | |
379 | |
380 | |
381 static void dm_mem_fclose(DMResource * f) | |
382 { | |
383 f->dataSize = 0; | |
384 f->dataOffset = 0; | |
385 dmFree(f->data); | |
386 f->data = NULL; | |
387 } | |
388 | |
389 | |
390 static int dm_mem_ferror(DMResource * f) | |
391 { | |
392 return f->error; | |
393 } | |
394 | |
395 | |
396 static int dm_mem_fseek(DMResource * f, const off_t offset, const int whence) | |
397 { | |
398 off_t newPos; | |
399 | |
400 // Calculate the new position | |
401 switch (whence) | |
402 { | |
403 case SEEK_SET: | |
404 newPos = offset; | |
405 break; | |
406 | |
407 case SEEK_CUR: | |
408 newPos = f->dataOffset + offset; | |
409 break; | |
410 | |
411 case SEEK_END: | |
412 newPos = f->dataSize + offset; | |
413 break; | |
414 | |
415 default: | |
416 return -1; | |
417 } | |
418 | |
419 // Set the new position | |
420 f->dataOffset = newPos; | |
421 | |
422 // Check the new position | |
423 if (newPos < 0 && (size_t) newPos >= f->dataSize) | |
424 return -1; | |
425 | |
426 return 0; | |
427 } | |
428 | |
429 | |
430 static off_t dm_mem_fsize(DMResource * f) | |
431 { | |
432 return f->dataSize; | |
433 } | |
434 | |
435 | |
436 static off_t dm_mem_ftell(DMResource * f) | |
437 { | |
438 return f->dataOffset; | |
439 } | |
440 | |
441 | |
442 static BOOL dm_mem_feof(DMResource * f) | |
443 { | |
444 // Check for EOF | |
445 if ((size_t) f->dataOffset <= f->dataSize) | |
446 return FALSE; | |
447 else | |
448 return TRUE; | |
449 } | |
450 | |
451 | |
452 static int dm_mem_fgetc(DMResource * f) | |
453 { | |
454 // Check for EOF | |
455 if ((size_t) f->dataOffset < f->dataSize) | |
456 return (int) f->data[f->dataOffset++]; | |
457 else | |
458 return EOF; | |
459 } | |
460 | |
461 | |
462 static size_t dm_mem_fread(void *buf, size_t size, size_t nmemb, DMResource * f) | |
463 { | |
464 size_t length = (size * nmemb); | |
465 | |
466 // Check if we can read the whole chunk | |
467 if (((size_t) f->dataOffset + length) >= f->dataSize) | |
468 { | |
469 nmemb = (f->dataSize - f->dataOffset) / size; | |
470 length = size * nmemb; | |
471 } | |
472 | |
473 memcpy(buf, f->data + f->dataOffset, length); | |
474 f->dataOffset += length; | |
475 return nmemb; | |
476 } | |
477 | |
478 | |
479 DMResourceOps dfPackFileOps = | |
480 { | |
481 dm_mem_ferror, | |
482 dm_mem_fseek, | |
483 dm_mem_fsize, | |
484 dm_mem_ftell, | |
485 dm_mem_feof, | |
486 dm_mem_fgetc, | |
487 dm_mem_fread, | |
488 | |
489 NULL, | |
490 dm_mem_fclose, | |
491 dm_pack_preload | |
492 }; | |
493 | |
494 | |
495 DMResourceOps dfMemIOFileOps = | |
496 { | |
497 dm_mem_ferror, | |
498 dm_mem_fseek, | |
499 dm_mem_fsize, | |
500 dm_mem_ftell, | |
501 dm_mem_feof, | |
502 dm_mem_fgetc, | |
503 dm_mem_fread, | |
504 | |
505 NULL, | |
506 NULL, | |
507 NULL | |
508 }; | |
509 | |
510 | |
511 /* FS file handling functions. These functions call the actual | |
512 * functions depending on where the file is located. | |
513 */ | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
514 static void dmf_init_fops(DMResource *handle) |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
515 { |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
516 // Check fops |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
517 if (handle->fops == NULL) |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
518 { |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
519 #ifdef DMRES_PACKFS |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
520 if (dfResFlags & DRF_USE_PACK) |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
521 handle->fops = &dfPackFileOps; |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
522 #ifdef DMRES_STDIO |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
523 else |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
524 handle->fops = &dfStdioFileOps; |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
525 #else |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
526 handle->fops = &dfPackFileOps; |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
527 #endif |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
528 |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
529 #else |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
530 handle->fops = &dfStdioFileOps; |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
531 #endif |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
532 } |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
533 } |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
534 |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
535 |
0 | 536 DMResource *dmf_open(const char *filename) |
537 { | |
538 int ret; | |
539 DMResource *handle; | |
540 | |
541 // Check master directory for resource | |
542 if ((handle = dmres_find(filename)) == NULL) | |
543 { | |
544 #ifdef DMRES_STDIO | |
545 // Hmm.. does not exist? Fall back to a stdio file | |
546 handle = dmres_new(filename, 0, 0); | |
547 if (handle == NULL) | |
548 return NULL; | |
549 | |
550 handle->fops = &dfStdioFileOps; | |
551 dmres_insert(handle); | |
552 #else | |
553 // Stdio not enabled, fail | |
554 return NULL; | |
555 #endif | |
556 } | |
557 | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
558 dmf_init_fops(handle); |
0 | 559 |
560 // Check if the data is preloaded | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
561 if (handle->flags & DMF_LOADED_RAW) |
0 | 562 { |
563 dmres_ref(handle); | |
564 return handle; | |
565 } | |
566 | |
567 // Check if we want to preload .. | |
568 ret = DMERR_INIT_FAIL; | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
569 if (((handle->flags & DMF_PRELOAD_RAW) || (dfResFlags & DRF_PRELOAD_ALL)) && |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
570 (handle->flags & DMF_LOADED_RAW) == 0 && |
0 | 571 handle->fops->preload != NULL) |
572 ret = handle->fops->preload(handle); | |
573 else | |
574 { | |
575 if (handle->fops->fopen != NULL) | |
576 ret = handle->fops->fopen(handle); | |
577 else | |
578 if (handle->fops->preload != NULL) | |
579 ret = handle->fops->preload(handle); | |
580 } | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
581 |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
582 if (((handle->flags & DMF_PRELOAD_RES) || (dfResFlags & DRF_PRELOAD_RES)) && |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
583 (handle->flags & DMF_LOADED_RES) == 0 && |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
584 handle->rops != NULL && |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
585 handle->rops->load != NULL) |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
586 ret = handle->rops->load(handle); |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
587 |
0 | 588 |
589 if (ret == DMERR_OK) | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
590 { |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
591 dmres_ref(handle); |
0 | 592 return handle; |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
593 } |
0 | 594 |
595 return NULL; | |
596 } | |
597 | |
598 | |
599 DMResource * dmf_open_memio(const char *filename, Uint8 *buf, size_t len) | |
600 { | |
601 DMResource *handle; | |
602 | |
603 // Check master directory for resource | |
604 if ((handle = dmres_find(filename)) == NULL) | |
605 { | |
606 // Hmm.. does not exist? Fall back to a stdio file | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
607 handle = dmres_new(filename, DMF_LOADED_RAW, len); |
0 | 608 if (handle == NULL) |
609 return NULL; | |
610 | |
611 handle->fops = &dfMemIOFileOps; | |
612 handle->data = buf; | |
613 dmres_insert(handle); | |
614 } | |
615 | |
616 // Increase refcount | |
617 dmres_ref(handle); | |
618 | |
619 return handle; | |
620 } | |
621 | |
622 | |
623 #ifdef DMRES_STDIO | |
624 DMResource * dmf_create_stdio(const char *filename) | |
625 { | |
626 DMResource *handle = dmres_new(filename, 0, 0); | |
627 if (handle == NULL) | |
628 return NULL; | |
629 | |
630 handle->fops = &dfStdioFileOps; | |
631 | |
632 handle->fh = fopen(filename, "rb"); | |
633 handle->error = dmGetErrno(); | |
634 | |
635 if (handle->fh != NULL) | |
636 { | |
637 dmres_ref(handle); | |
638 return handle; | |
639 } | |
640 else | |
641 { | |
642 dmres_free(handle); | |
643 return NULL; | |
644 } | |
645 } | |
646 | |
647 | |
648 DMResource * dmf_create_stdio_stream(FILE *fh) | |
649 { | |
650 DMResource *handle = dmres_new("", 0, 0); | |
651 if (handle == NULL) | |
652 return NULL; | |
653 | |
654 handle->fops = &dfStdioFHOps; | |
655 handle->fh = fh; | |
656 dmres_ref(handle); | |
657 return handle; | |
658 } | |
659 #endif | |
660 | |
661 | |
662 void dmf_close(DMResource * f) | |
663 { | |
664 if (f == NULL) | |
665 return; | |
666 | |
667 if (f->fops->fclose != NULL) | |
668 f->fops->fclose(f); | |
669 | |
670 dmres_unref(f); | |
671 } | |
672 | |
673 | |
674 int dmferror(DMResource * f) | |
675 { | |
676 f->atime = time(NULL); | |
677 return f->fops->ferror(f); | |
678 } | |
679 | |
680 int dmfseek(DMResource * f, off_t offset, int whence) | |
681 { | |
682 f->atime = time(NULL); | |
683 return f->fops->fseek(f, offset, whence); | |
684 } | |
685 | |
686 off_t dmfsize(DMResource * f) | |
687 { | |
688 f->atime = time(NULL); | |
689 return f->fops->fsize(f); | |
690 } | |
691 | |
692 off_t dmftell(DMResource * f) | |
693 { | |
694 f->atime = time(NULL); | |
695 return f->fops->ftell(f); | |
696 } | |
697 | |
698 BOOL dmfeof(DMResource * f) | |
699 { | |
700 f->atime = time(NULL); | |
701 return f->fops->feof(f); | |
702 } | |
703 | |
704 int dmfgetc(DMResource * f) | |
705 { | |
706 f->atime = time(NULL); | |
707 return f->fops->fgetc(f); | |
708 } | |
709 | |
710 size_t dmfread(void *ptr, size_t size, size_t nmemb, DMResource * f) | |
711 { | |
712 f->atime = time(NULL); | |
713 return f->fops->fread(ptr, size, nmemb, f); | |
714 } | |
715 | |
716 | |
27
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
717 int dmres_ref(DMResource *node) |
0 | 718 { |
719 DMRES_LOCK(); | |
27
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
720 node->atime = time(NULL); |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
721 node->refcount++; |
0 | 722 DMRES_UNLOCK(); |
723 | |
27
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
724 return node->refcount; |
0 | 725 } |
726 | |
727 | |
27
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
728 int dmres_unref(DMResource *node) |
0 | 729 { |
730 DMRES_LOCK(); | |
27
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
731 node->refcount--; |
0 | 732 DMRES_UNLOCK(); |
733 | |
27
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
734 return node->refcount; |
0 | 735 } |
736 | |
737 | |
738 int dmres_load_resfile(const char *filename) | |
739 { | |
740 int ret; | |
741 char line[256]; | |
742 FILE *f = fopen(filename, "r"); | |
743 if (f == NULL) | |
744 return DMERR_FOPEN; | |
745 | |
746 DMRES_LOCK(); | |
747 | |
748 while (fgets(line, sizeof(line) - 1, f) != NULL) | |
749 { | |
750 int fnstart, fsep; | |
751 for (fnstart = 0; isspace(line[fnstart]); fnstart++); | |
752 for (fsep = fnstart; line[fsep] && line[fsep] != '|'; fsep++); | |
753 if (line[fsep] == '|') | |
754 { | |
755 int flags, i; | |
756 for (i = fsep - 1; i > 0 && isspace(line[i]); i--) | |
757 line[i] = 0; | |
758 | |
759 for (i = fsep; isspace(line[i]); i++); | |
760 | |
761 if (sscanf(&line[i], "%x", &flags) == 1 && | |
762 strlen(&line[fnstart]) > 0) | |
763 { | |
764 | |
765 } | |
766 } | |
767 } | |
768 | |
769 DMRES_UNLOCK(); | |
770 fclose(f); | |
771 return ret; | |
772 } | |
773 | |
774 | |
775 int dmres_write_resfile(const char *filename) | |
776 { | |
777 int ret; | |
778 DMResource *node; | |
779 FILE *f = fopen(filename, "w"); | |
780 if (f == NULL) | |
781 return DMERR_FOPEN; | |
782 | |
783 DMRES_LOCK(); | |
784 | |
785 for (node = dfResources; node != NULL; node = node->next) | |
786 { | |
787 if (fprintf(f, "%s|%08x\n", node->filename, node->flags) < 0) | |
788 { | |
789 ret = DMERR_FWRITE; | |
790 goto error; | |
791 } | |
792 } | |
793 | |
794 error: | |
795 DMRES_UNLOCK(); | |
796 fclose(f); | |
797 return ret; | |
798 } | |
799 | |
800 | |
801 /* Resources subsystem initialization and shutdown routines | |
802 */ | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
803 int dmres_init(const char *filename, const char *path, int flags, int (*classifier)(DMResource *)) |
0 | 804 { |
805 // Check if we are already initialized | |
806 if (dfResInitialized) | |
807 return DMERR_ALREADY_INIT; | |
808 | |
809 dfResFlags = flags; | |
810 dfResPath = dm_strdup((path != NULL) ? path : DMRES_DATA_PATH); | |
811 dfResourcesMutex = dmCreateMutex(); | |
812 | |
813 if (flags & DRF_USE_PACK) | |
814 { | |
815 #ifdef DMRES_PACKFS | |
816 int ret; | |
817 DMPackEntry *node; | |
818 | |
819 dfResPackFilename = dm_strdup((filename != NULL) ? filename : DMRES_DATA_PACK); | |
820 | |
821 // Initialize PACK, open as read-only | |
822 ret = dm_pack_open(dfResPackFilename, &dfResPackFile, TRUE); | |
823 if (ret != DMERR_OK) | |
824 { | |
825 dmError("Error opening PACK file '%s', #%i: %s\n", | |
826 dfResPackFilename, ret, dmErrorStr(ret)); | |
827 | |
828 return DMERR_INIT_FAIL; | |
829 } | |
830 | |
831 // Initialize resources from a PACK file | |
832 for (node = dfResPackFile->entries; node != NULL; node = node->next) | |
833 { | |
4
e0fc7863d024
Mask out bits from resFlags that should not be there after initialization.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
834 DMResource *res = dmres_new(node->filename, node->resFlags & DMF_MASK, node->size); |
0 | 835 if (res == NULL) |
836 { | |
837 dmError("Could not allocate memory for resource node '%s' [0x%08x], %d.\n", | |
838 node->filename, node->resFlags, node->size); | |
839 return DMERR_INIT_FAIL; | |
840 } | |
841 | |
842 dmres_insert(res); | |
843 } | |
844 | |
845 #else | |
846 // PACK not compiled in, FAIL! | |
847 return DMERR_INIT_FAIL; | |
848 #endif | |
849 } | |
850 else | |
851 { | |
852 // Initialize resources from a resource directory | |
853 char *resFilename = dm_strdup_printf("%s%s", dfResPath, DMRES_RES_FILE); | |
854 int ret = dmres_load_resfile(resFilename); | |
855 dmFree(resFilename); | |
856 | |
857 if (ret != DMERR_OK) | |
858 return DMERR_INIT_FAIL; | |
859 } | |
860 | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
861 // Okay, classify resources |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
862 if (dfResources != NULL && classifier != NULL) |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
863 { |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
864 DMResource *node; |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
865 for (node = dfResources; node != NULL; node = node->next) |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
866 { |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
867 int ret = classifier(node); |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
868 if (ret != DMERR_OK) |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
869 return DMERR_INIT_FAIL; |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
870 } |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
871 } |
0 | 872 |
873 // Initialization complete | |
874 dfResInitialized = TRUE; | |
875 return DMERR_OK; | |
876 } | |
877 | |
878 | |
879 void dmres_close(void) | |
880 { | |
881 DMResource *node; | |
882 DMRES_LOCK(); | |
883 | |
884 if (!dfResInitialized) | |
885 return; | |
886 | |
887 // Shutdown possible subsystems | |
888 #ifdef DMRES_PACKFS | |
889 if (dfResFlags & DRF_USE_PACK) | |
890 { | |
891 int res = dm_pack_close(dfResPackFile); | |
892 if (res != DMERR_OK) | |
893 { | |
894 dmError("Error closing PACK, #%i: %s\n", | |
895 res, dmErrorStr(res)); | |
896 } | |
897 | |
898 dmFree(dfResPackFilename); | |
899 } | |
900 #endif | |
901 | |
902 // Free resource entries | |
903 node = dfResources; | |
904 while (node != NULL) | |
905 { | |
906 DMResource *next = node->next; | |
907 dmres_free(node); | |
908 node = next; | |
909 } | |
910 | |
911 // Etc. | |
912 dmFree(dfResPath); | |
913 DMRES_UNLOCK(); | |
914 dmDestroyMutex(dfResourcesMutex); | |
915 dfResInitialized = FALSE; | |
916 } | |
917 | |
918 | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
919 int dmres_preload(BOOL start, int *loaded, int *total) |
0 | 920 { |
921 static DMResource *dfPreload = NULL; | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
922 int ret = DMERR_OK; |
0 | 923 |
924 DMRES_LOCK(); | |
925 | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
926 // Initialize preloading |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
927 if (dfPreload == NULL || start) |
0 | 928 { |
929 DMResource *node; | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
930 |
0 | 931 dfPreload = dfResources; |
932 *loaded = 0; | |
933 *total = 0; | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
934 |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
935 // Calculate total number of resources to be preloaded |
0 | 936 for (node = dfResources; node != NULL; node = node->next) |
937 { | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
938 if ((dfResFlags & (DRF_PRELOAD_ALL | DRF_PRELOAD_RES)) || |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
939 (node->flags & (DMF_PRELOAD_RAW | DMF_PRELOAD_RES))) |
0 | 940 (*total)++; |
941 } | |
942 } | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
943 else |
0 | 944 if (dfPreload != NULL) |
945 { | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
946 // Check if the raw resource wants to be preloaded |
27
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
947 if (((dfPreload->flags & DMF_PRELOAD_RAW) || |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
948 (dfResFlags & DRF_PRELOAD_ALL)) && |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
949 (dfPreload->flags & DMF_LOADED_RAW) == 0) |
0 | 950 { |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
951 dmf_init_fops(dfPreload); |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
952 if (dfPreload->fops->preload != NULL) |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
953 { |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
954 ret = dfPreload->fops->preload(dfPreload); |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
955 if (ret == DMERR_OK) |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
956 { |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
957 dfPreload->flags |= DMF_LOADED_RAW; |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
958 (*loaded)++; |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
959 } |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
960 else |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
961 goto error; |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
962 } |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
963 } |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
964 |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
965 // Preload actual resource, if requested |
27
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
966 if (((dfPreload->flags & DMF_PRELOAD_RES) || |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
967 (dfResFlags & DRF_PRELOAD_RES)) && |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
968 (dfPreload->flags & DMF_LOADED_RES) == 0 && |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
969 dfPreload->rops != NULL && |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
970 dfPreload->rops->load != NULL) |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
971 { |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
972 dmf_init_fops(dfPreload); |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
973 ret = dfPreload->rops->load(dfPreload); |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
974 if (ret != DMERR_OK) |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
975 goto error; |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
976 |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
977 dfPreload->flags |= DMF_LOADED_RES; |
0 | 978 } |
979 | |
980 dfPreload = dfPreload->next; | |
981 } | |
982 | |
983 DMRES_UNLOCK(); | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
984 return (dfPreload == NULL) ? DMERR_OK : DMERR_PROGRESS; |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
985 |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
986 error: |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
987 DMRES_UNLOCK(); |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
988 return ret; |
0 | 989 } |
990 | |
991 | |
992 void dmres_prune(int agems, int flags) | |
993 { | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
994 DMResource *node; |
0 | 995 int currtime = time(NULL); |
996 DMRES_LOCK(); | |
997 | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
998 for (node = dfResources; node != NULL; node = node->next) |
0 | 999 { |
1000 // Check if node has refcount of 0 and is | |
1001 // not marked as persistent resource | |
26
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1002 if (node->refcount == 0 && |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1003 (node->flags & DMF_PERSIST) == 0 && |
2f463a59d732
Implement rudimentary resource system.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1004 (node->flags & (DMF_LOADED_RES | DMF_LOADED_RAW))) |
0 | 1005 { |
1006 // Check if we match either one of atime or mtime | |
1007 if (((flags & DMPRUNE_ATIME) && | |
1008 currtime - node->atime >= agems) || | |
1009 ((flags & DMPRUNE_MTIME) && | |
1010 currtime - node->mtime >= agems)) | |
1011 { | |
27
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
1012 dmres_free_res_data(node); |
21c14afbf63d
Modularize the resource system a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
26
diff
changeset
|
1013 dmres_free_raw_data(node); |
0 | 1014 } |
1015 } | |
1016 } | |
1017 | |
1018 DMRES_UNLOCK(); | |
1019 } | |
1020 | |
1021 | |
1022 /* Helper resource access routines | |
1023 */ | |
1024 int dmf_read_str(DMResource *f, Uint8 *s, size_t l) | |
1025 { | |
1026 return dmfread(s, sizeof(Uint8), l, f) == l; | |
1027 } | |
1028 | |
1029 | |
1030 #define DM_DEFINE_FUNC(xname, xtype, xmacro) \ | |
1031 BOOL dmf_read_ ## xname (DMResource *f, xtype *v) { \ | |
1032 xtype result; \ | |
1033 if (dmfread(&result, sizeof( xtype ), 1, f) != 1) \ | |
1034 return FALSE; \ | |
1035 *v = DM_ ## xmacro ## _TO_NATIVE (result); \ | |
1036 return TRUE; \ | |
1037 } | |
1038 | |
1039 DM_DEFINE_FUNC(le16, Uint16, LE16) | |
1040 DM_DEFINE_FUNC(le32, Uint32, LE32) | |
1041 | |
1042 DM_DEFINE_FUNC(be16, Uint16, BE16) | |
1043 DM_DEFINE_FUNC(be32, Uint32, BE32) | |
1044 | |
1045 #ifdef DM_HAVE_64BIT | |
1046 DM_DEFINE_FUNC(le64, Uint64, LE64) | |
1047 DM_DEFINE_FUNC(be64, Uint64, BE64) | |
1048 #endif |