Skip to content

Commit 474947d

Browse files
committed
WAD: put doom level element in folder, ignore other tags
1 parent 957176b commit 474947d

File tree

1 file changed

+76
-3
lines changed

1 file changed

+76
-3
lines changed

src/physfs_archiver_wad.c

+76-3
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,62 @@
4747

4848
#if PHYSFS_SUPPORTS_WAD
4949

50+
const char *map_lumps[] = {
51+
"BLOCKMAP",
52+
"LINEDEFS",
53+
"NODES",
54+
"REJECT",
55+
"SECTORS",
56+
"SEGS",
57+
"SIDEDEFS",
58+
"SSECTORS",
59+
"THINGS",
60+
"VERTEXES",
61+
NULL,
62+
};
63+
64+
static int is_digit(char c) {
65+
return c >= '0' && c <= '9';
66+
}
67+
68+
static int is_map_lump(const char *name) {
69+
const char **lump;
70+
71+
for (lump = map_lumps; *lump; lump++) {
72+
if (strcmp(name, *lump) == 0) {
73+
return 1;
74+
}
75+
}
76+
return 0;
77+
}
78+
79+
static int is_doom_map_name(const char *name) {
80+
size_t len = strlen(name);
81+
82+
if (len == 4 && name[0] == 'E' && is_digit(name[1]) && name[2] == 'M' && is_digit(name [3])) {
83+
/* ExMy */
84+
return 1;
85+
}
86+
if (len == 5 && strncmp(name, "MAP", 3) == 0 && is_digit(name[3]) && is_digit(name[4])) {
87+
/* MAPxx */
88+
return 1;
89+
}
90+
return 0;
91+
}
92+
5093
static int wadLoadEntries(PHYSFS_Io *io, const PHYSFS_uint32 count, void *arc)
5194
{
95+
char path[8 + 1 + 8 + 1];
96+
size_t parent_pos = 0;
5297
PHYSFS_uint32 i;
98+
99+
path[0] = '\0';
100+
53101
for (i = 0; i < count; i++)
54102
{
55103
PHYSFS_uint32 pos;
56104
PHYSFS_uint32 size;
105+
int is_directory;
57106
char name[9];
58107

59108
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &pos, 4), 0);
@@ -63,7 +112,31 @@ static int wadLoadEntries(PHYSFS_Io *io, const PHYSFS_uint32 count, void *arc)
63112
name[8] = '\0'; /* name might not be null-terminated in file. */
64113
size = PHYSFS_swapULE32(size);
65114
pos = PHYSFS_swapULE32(pos);
66-
BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, -1, -1, pos, size), 0);
115+
is_directory = 0;
116+
117+
if (size == 0) {
118+
if (is_doom_map_name(name)) {
119+
strcpy(path, name);
120+
parent_pos = strlen(path);
121+
is_directory = 1;
122+
} else {
123+
/* Ignore _START and _END tags */
124+
continue;
125+
}
126+
} else {
127+
if (parent_pos) {
128+
if (is_map_lump(name)) {
129+
strcat(path, "/");
130+
strcpy(path + 1 + parent_pos, name);
131+
} else {
132+
parent_pos = 0;
133+
strcpy(path, name);
134+
}
135+
} else {
136+
strcpy(path, name);
137+
}
138+
}
139+
BAIL_IF_ERRPASS(!UNPK_addEntry(arc, path, is_directory, -1, -1, pos, size), 0);
67140
} /* for */
68141

69142
return 1;
@@ -90,10 +163,10 @@ static void *WAD_openArchive(PHYSFS_Io *io, const char *name,
90163
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &count, sizeof (count)), NULL);
91164
count = PHYSFS_swapULE32(count);
92165

93-
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &directoryOffset, 4), 0);
166+
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &directoryOffset, 4), NULL);
94167
directoryOffset = PHYSFS_swapULE32(directoryOffset);
95168

96-
BAIL_IF_ERRPASS(!io->seek(io, directoryOffset), 0);
169+
BAIL_IF_ERRPASS(!io->seek(io, directoryOffset), NULL);
97170

98171
unpkarc = UNPK_openArchive(io, 0, 1);
99172
BAIL_IF_ERRPASS(!unpkarc, NULL);

0 commit comments

Comments
 (0)