Skip to content

Commit a8bd37c

Browse files
committed
WAD: add support for tags and labels
Labeled and tagged lumps are put in a folder.
1 parent 57d36e0 commit a8bd37c

File tree

1 file changed

+54
-3
lines changed

1 file changed

+54
-3
lines changed

src/physfs_archiver_wad.c

+54-3
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,25 @@
4747

4848
#if PHYSFS_SUPPORTS_WAD
4949

50+
#define MAX_DEPTH 16
51+
5052
static int wadLoadEntries(PHYSFS_Io *io, const PHYSFS_uint32 count, void *arc)
5153
{
54+
PHYSFS_sint32 depth;
55+
char path[(MAX_DEPTH - 1) * 2 + 8 + MAX_DEPTH + 8 + 1];
56+
PHYSFS_uint32 parent_positions[MAX_DEPTH+1];
57+
int parent_is_label = 0;
5258
PHYSFS_uint32 i;
59+
60+
depth = 0;
61+
path[0] = '\0';
62+
parent_positions[0] = 0;
63+
5364
for (i = 0; i < count; i++)
5465
{
5566
PHYSFS_uint32 pos;
5667
PHYSFS_uint32 size;
68+
int is_directory;
5769
char name[9];
5870

5971
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &pos, 4), 0);
@@ -63,9 +75,48 @@ static int wadLoadEntries(PHYSFS_Io *io, const PHYSFS_uint32 count, void *arc)
6375
name[8] = '\0'; /* name might not be null-terminated in file. */
6476
size = PHYSFS_swapULE32(size);
6577
pos = PHYSFS_swapULE32(pos);
66-
BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, -1, -1, pos, size), 0);
78+
is_directory = 0;
79+
80+
if (size == 0) {
81+
size_t len = strlen(name);
82+
83+
if (parent_is_label) {
84+
BAIL_IF_ERRPASS(depth <= 0, 0);
85+
depth -= 1;
86+
parent_is_label = 0;
87+
}
88+
89+
if (len > 6 && strcmp(name + len - 6, "_START") == 0) {
90+
BAIL_IF_ERRPASS(depth > MAX_DEPTH, 0);
91+
is_directory = 1;
92+
93+
strncpy(path + parent_positions[depth], name, len - 6);
94+
strcpy(path + parent_positions[depth] + len - 6, "/");
95+
depth += 1;
96+
parent_positions[depth] = parent_positions[depth - 1] + len - 5;
97+
} else if (len > 4 && strcmp(name + len - 4, "_END") == 0) {
98+
BAIL_IF_ERRPASS(depth <= 0, 0);
99+
100+
depth -= 1;
101+
} else {
102+
BAIL_IF_ERRPASS(depth > MAX_DEPTH, 0);
103+
is_directory = 1;
104+
parent_is_label = 1;
105+
106+
strncpy(path + parent_positions[depth], name, len);
107+
strcpy(path + parent_positions[depth] + len, "/");
108+
depth += 1;
109+
parent_positions[depth] = parent_positions[depth - 1] + len + 1;
110+
}
111+
continue;
112+
} else {
113+
strcpy(path + parent_positions[depth], name);
114+
}
115+
BAIL_IF_ERRPASS(!UNPK_addEntry(arc, path, is_directory, -1, -1, pos, size), 0);
67116
} /* for */
68117

118+
BAIL_IF_ERRPASS(depth != 0, 0);
119+
69120
return 1;
70121
} /* wadLoadEntries */
71122

@@ -90,10 +141,10 @@ static void *WAD_openArchive(PHYSFS_Io *io, const char *name,
90141
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &count, sizeof (count)), NULL);
91142
count = PHYSFS_swapULE32(count);
92143

93-
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &directoryOffset, 4), 0);
144+
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &directoryOffset, 4), NULL);
94145
directoryOffset = PHYSFS_swapULE32(directoryOffset);
95146

96-
BAIL_IF_ERRPASS(!io->seek(io, directoryOffset), 0);
147+
BAIL_IF_ERRPASS(!io->seek(io, directoryOffset), NULL);
97148

98149
unpkarc = UNPK_openArchive(io, 0, 1);
99150
BAIL_IF_ERRPASS(!unpkarc, NULL);

0 commit comments

Comments
 (0)