1 /* |
|
2 * MVL support routines for PhysicsFS. |
|
3 * |
|
4 * This driver handles Descent II Movielib archives. |
|
5 * |
|
6 * The file format of MVL is quite easy... |
|
7 * |
|
8 * //MVL File format - Written by Heiko Herrmann |
|
9 * char sig[4] = {'D','M', 'V', 'L'}; // "DMVL"=Descent MoVie Library |
|
10 * |
|
11 * int num_files; // the number of files in this MVL |
|
12 * |
|
13 * struct { |
|
14 * char file_name[13]; // Filename, padded to 13 bytes with 0s |
|
15 * int file_size; // filesize in bytes |
|
16 * }DIR_STRUCT[num_files]; |
|
17 * |
|
18 * struct { |
|
19 * char data[file_size]; // The file data |
|
20 * }FILE_STRUCT[num_files]; |
|
21 * |
|
22 * (That info is from http://www.descent2.com/ddn/specs/mvl/) |
|
23 * |
|
24 * Please see the file LICENSE.txt in the source's root directory. |
|
25 * |
|
26 * This file written by Bradley Bell. |
|
27 * Based on grp.c by Ryan C. Gordon. |
|
28 */ |
|
29 |
|
30 #define __PHYSICSFS_INTERNAL__ |
|
31 #include "physfs_internal.h" |
|
32 |
|
33 #if PHYSFS_SUPPORTS_MVL |
|
34 |
|
35 static UNPKentry *mvlLoadEntries(PHYSFS_Io *io, PHYSFS_uint32 fileCount) |
|
36 { |
|
37 PHYSFS_uint32 location = 8; /* sizeof sig. */ |
|
38 UNPKentry *entries = NULL; |
|
39 UNPKentry *entry = NULL; |
|
40 |
|
41 entries = (UNPKentry *) allocator.Malloc(sizeof (UNPKentry) * fileCount); |
|
42 BAIL_IF_MACRO(entries == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL); |
|
43 |
|
44 location += (17 * fileCount); |
|
45 |
|
46 for (entry = entries; fileCount > 0; fileCount--, entry++) |
|
47 { |
|
48 if (!__PHYSFS_readAll(io, &entry->name, 13)) goto failed; |
|
49 if (!__PHYSFS_readAll(io, &entry->size, 4)) goto failed; |
|
50 entry->size = PHYSFS_swapULE32(entry->size); |
|
51 entry->startPos = location; |
|
52 location += entry->size; |
|
53 } /* for */ |
|
54 |
|
55 return entries; |
|
56 |
|
57 failed: |
|
58 allocator.Free(entries); |
|
59 return NULL; |
|
60 } /* mvlLoadEntries */ |
|
61 |
|
62 |
|
63 static void *MVL_openArchive(PHYSFS_Io *io, const char *name, int forWriting) |
|
64 { |
|
65 PHYSFS_uint8 buf[4]; |
|
66 PHYSFS_uint32 count = 0; |
|
67 UNPKentry *entries = NULL; |
|
68 |
|
69 assert(io != NULL); /* shouldn't ever happen. */ |
|
70 BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL); |
|
71 BAIL_IF_MACRO(!__PHYSFS_readAll(io, buf, 4), ERRPASS, NULL); |
|
72 BAIL_IF_MACRO(memcmp(buf, "DMVL", 4) != 0, PHYSFS_ERR_UNSUPPORTED, NULL); |
|
73 BAIL_IF_MACRO(!__PHYSFS_readAll(io, &count, sizeof(count)), ERRPASS, NULL); |
|
74 |
|
75 count = PHYSFS_swapULE32(count); |
|
76 entries = mvlLoadEntries(io, count); |
|
77 return (!entries) ? NULL : UNPK_openArchive(io, entries, count); |
|
78 } /* MVL_openArchive */ |
|
79 |
|
80 |
|
81 const PHYSFS_Archiver __PHYSFS_Archiver_MVL = |
|
82 { |
|
83 { |
|
84 "MVL", |
|
85 "Descent II Movielib format", |
|
86 "Bradley Bell <btb@icculus.org>", |
|
87 "http://icculus.org/physfs/", |
|
88 }, |
|
89 MVL_openArchive, /* openArchive() method */ |
|
90 UNPK_enumerateFiles, /* enumerateFiles() method */ |
|
91 UNPK_openRead, /* openRead() method */ |
|
92 UNPK_openWrite, /* openWrite() method */ |
|
93 UNPK_openAppend, /* openAppend() method */ |
|
94 UNPK_remove, /* remove() method */ |
|
95 UNPK_mkdir, /* mkdir() method */ |
|
96 UNPK_closeArchive, /* closeArchive() method */ |
|
97 UNPK_stat /* stat() method */ |
|
98 }; |
|
99 |
|
100 #endif /* defined PHYSFS_SUPPORTS_MVL */ |
|
101 |
|
102 /* end of mvl.c ... */ |
|
103 |
|