Skip to content

Commit 6b147f6

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

File tree

1 file changed

+77
-3
lines changed

1 file changed

+77
-3
lines changed

src/physfs_archiver_wad.c

+77-3
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,63 @@
4747

4848
#if PHYSFS_SUPPORTS_WAD
4949

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

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

69143
return 1;
@@ -90,10 +164,10 @@ static void *WAD_openArchive(PHYSFS_Io *io, const char *name,
90164
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &count, sizeof (count)), NULL);
91165
count = PHYSFS_swapULE32(count);
92166

93-
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &directoryOffset, 4), 0);
167+
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &directoryOffset, 4), NULL);
94168
directoryOffset = PHYSFS_swapULE32(directoryOffset);
95169

96-
BAIL_IF_ERRPASS(!io->seek(io, directoryOffset), 0);
170+
BAIL_IF_ERRPASS(!io->seek(io, directoryOffset), NULL);
97171

98172
unpkarc = UNPK_openArchive(io, 0, 1);
99173
BAIL_IF_ERRPASS(!unpkarc, NULL);

0 commit comments

Comments
 (0)