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+
5093static 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