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 int mvlLoadEntries(PHYSFS_Io *io, const PHYSFS_uint32 count, void *arc) |
36 | { |
37 | PHYSFS_uint32 pos = 8 + (17 * count); /* past sig+metadata. */ |
38 | PHYSFS_uint32 i; |
39 | |
40 | for (i = 0; i < count; i++) |
41 | { |
42 | PHYSFS_uint32 size; |
43 | char name[13]; |
44 | BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, name, 13), 0); |
45 | BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &size, 4), 0); |
46 | name[12] = '\0'; /* just in case. */ |
47 | size = PHYSFS_swapULE32(size); |
48 | BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, -1, -1, pos, size), 0); |
49 | pos += size; |
50 | } /* for */ |
51 | |
52 | return 1; |
53 | } /* mvlLoadEntries */ |
54 | |
55 | |
56 | static void *MVL_openArchive(PHYSFS_Io *io, const char *name, |
57 | int forWriting, int *claimed) |
58 | { |
59 | PHYSFS_uint8 buf[4]; |
60 | PHYSFS_uint32 count = 0; |
61 | void *unpkarc; |
62 | |
63 | assert(io != NULL); /* shouldn't ever happen. */ |
64 | BAIL_IF(forWriting, PHYSFS_ERR_READ_ONLY, NULL); |
65 | BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, buf, 4), NULL); |
66 | BAIL_IF(memcmp(buf, "DMVL" , 4) != 0, PHYSFS_ERR_UNSUPPORTED, NULL); |
67 | |
68 | *claimed = 1; |
69 | |
70 | BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &count, sizeof(count)), NULL); |
71 | count = PHYSFS_swapULE32(count); |
72 | |
73 | unpkarc = UNPK_openArchive(io, 0, 1); |
74 | BAIL_IF_ERRPASS(!unpkarc, NULL); |
75 | |
76 | if (!mvlLoadEntries(io, count, unpkarc)) |
77 | { |
78 | UNPK_abandonArchive(unpkarc); |
79 | return NULL; |
80 | } /* if */ |
81 | |
82 | return unpkarc; |
83 | } /* MVL_openArchive */ |
84 | |
85 | |
86 | const PHYSFS_Archiver __PHYSFS_Archiver_MVL = |
87 | { |
88 | CURRENT_PHYSFS_ARCHIVER_API_VERSION, |
89 | { |
90 | "MVL" , |
91 | "Descent II Movielib format" , |
92 | "Bradley Bell <btb@icculus.org>" , |
93 | "https://icculus.org/physfs/" , |
94 | 0, /* supportsSymlinks */ |
95 | }, |
96 | MVL_openArchive, |
97 | UNPK_enumerate, |
98 | UNPK_openRead, |
99 | UNPK_openWrite, |
100 | UNPK_openAppend, |
101 | UNPK_remove, |
102 | UNPK_mkdir, |
103 | UNPK_stat, |
104 | UNPK_closeArchive |
105 | }; |
106 | |
107 | #endif /* defined PHYSFS_SUPPORTS_MVL */ |
108 | |
109 | /* end of physfs_archiver_mvl.c ... */ |
110 | |
111 | |