/* iwad64ex.c : Extracts the embedded IWAD in Hexen 64. Currently does not decompress the data (or fix the endianness in data). (C)2019 Marisa Kirisame, UnSX Team. Released under the GNU General Public License version 3. */ #include #include #include #include #include typedef struct { char sig[4]; uint32_t nlumps; uint32_t dirpos; } wad_t; typedef struct { uint32_t filepos, size; char name[8]; } lump_t; char *data; wad_t *wad; lump_t *lumps; uint32_t btl( uint32_t b ) { return ((b>>24)&0xff)|((b<<8)&0xff0000) |((b>>8)&0xff00)|((b<<24)&0xff000000); } int main( int argc, char **argv ) { if ( argc < 3 ) { fprintf(stderr,"usage: iwad64ex \n"); return 1; } FILE *romfile = fopen(argv[1],"rb"); if ( !romfile ) { fprintf(stderr,"failed to open %s for reading: %s\n", argv[1],strerror(errno)); return 2; } ssize_t fpos = 0; char buf[4096]; ssize_t found = 0; while ( !feof(romfile) ) { memset(buf,0,4096); int bsiz = fread(buf,1,4096,romfile); // to avoid GNU-exclusive memmem function I'll just roll out // my own thing here (fuckin' GNU and their exclusives...) for ( int i=0; inlumps = btl(wad->nlumps); wad->dirpos = btl(wad->dirpos); // reallocate to fit size_t fullsiz = wad->dirpos+wad->nlumps*16; data = realloc(data,fullsiz); wad = (wad_t*)data; if ( errno ) { fclose(romfile); free(data); fprintf(stderr,"cannot allocate %zd bytes for full wad: %s", fullsiz,strerror(errno)); return 32; } fread(data+12,1,fullsiz-12,romfile); lumps = (lump_t*)(data+wad->dirpos); // loop and fix endianness for ( int i=0; inlumps; i++ ) { lumps[i].filepos = btl(lumps[i].filepos); lumps[i].size = btl(lumps[i].size); printf("%.8s %d %d\n",lumps[i].name,lumps[i].size, lumps[i].filepos); } fclose(romfile); FILE *wadfile = fopen(argv[2],"wb"); if ( !wadfile ) { fprintf(stderr,"failed to open %s for writing: %s\n", argv[2],strerror(errno)); return 4; } fwrite(data,1,fullsiz,wadfile); fclose(wadfile); free(data); printf("wrote %s, %d bytes\n",argv[2],fullsiz); return 0; }