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