mirror of
https://github.com/ZDoom/wadext.git
synced 2024-11-21 19:32:32 +00:00
added unpacking of Quake 2 PAK files.
This commit is contained in:
parent
0a8f91e0b9
commit
c21268c13b
2 changed files with 143 additions and 0 deletions
137
wadext.cpp
137
wadext.cpp
|
@ -677,6 +677,85 @@ void ConvertTextureX()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// CreatePath
|
||||||
|
//
|
||||||
|
// Creates a directory including all levels necessary
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
#ifdef _WIN32
|
||||||
|
void CreatePath(const char* fn)
|
||||||
|
{
|
||||||
|
char drive[_MAX_DRIVE];
|
||||||
|
char dir[_MAX_DIR];
|
||||||
|
_splitpath_s(fn, drive, sizeof drive, dir, sizeof dir, nullptr, 0, nullptr, 0);
|
||||||
|
|
||||||
|
if ('\0' == *dir)
|
||||||
|
{
|
||||||
|
// Root/current/parent directory always exists
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char path[_MAX_PATH];
|
||||||
|
_makepath_s(path, sizeof path, drive, dir, nullptr, nullptr);
|
||||||
|
|
||||||
|
if ('\0' == *path)
|
||||||
|
{
|
||||||
|
// No need to process empty relative path
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove trailing path separator(s)
|
||||||
|
for (size_t i = strlen(path); 0 != i; --i)
|
||||||
|
{
|
||||||
|
char& lastchar = path[i - 1];
|
||||||
|
|
||||||
|
if ('/' == lastchar || '\\' == lastchar)
|
||||||
|
{
|
||||||
|
lastchar = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create all directories for given path
|
||||||
|
if ('\0' != *path)
|
||||||
|
{
|
||||||
|
CreatePath(path);
|
||||||
|
_mkdir(path); // PAKs are ASCII only, so we won't need Unicode extension.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
void CreatePath(const char* fn)
|
||||||
|
{
|
||||||
|
char* copy, * p;
|
||||||
|
|
||||||
|
if (fn[0] == '/' && fn[1] == '\0')
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p = copy = strdup(fn);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
p = strchr(p + 1, '/');
|
||||||
|
if (p != NULL)
|
||||||
|
{
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
mkdir(copy, 0755);
|
||||||
|
if (p != NULL)
|
||||||
|
{
|
||||||
|
*p = '/';
|
||||||
|
}
|
||||||
|
} while (p);
|
||||||
|
free(copy);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -738,3 +817,61 @@ void GrpExtract(const char* filename, FILE* f)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
struct dpackfile_t
|
||||||
|
{
|
||||||
|
char name[56];
|
||||||
|
uint32_t filepos, filelen;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dpackheader_t
|
||||||
|
{
|
||||||
|
uint32_t ident; // == IDPAKHEADER
|
||||||
|
uint32_t dirofs;
|
||||||
|
uint32_t dirlen;
|
||||||
|
};
|
||||||
|
|
||||||
|
void PakExtract(const char* filename, FILE* f)
|
||||||
|
{
|
||||||
|
TArray<dpackfile_t> fileinfo;
|
||||||
|
|
||||||
|
dpackheader_t header;
|
||||||
|
|
||||||
|
if (1 != fread(&header, sizeof(header), 1, f)) return;
|
||||||
|
|
||||||
|
if (memcmp(&header.ident, "PACK", 4))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fseek(f, header.dirofs, SEEK_SET);
|
||||||
|
|
||||||
|
uint32_t NumLumps = header.dirlen / sizeof(dpackfile_t);
|
||||||
|
fileinfo.Resize(NumLumps);
|
||||||
|
|
||||||
|
if (NumLumps != fread(&fileinfo[0], sizeof(dpackfile_t), NumLumps, f)) return;
|
||||||
|
auto name = ExtractFileBase(filename, false);
|
||||||
|
mkdir(name.c_str());
|
||||||
|
chdir(name.c_str());
|
||||||
|
|
||||||
|
TArray<char> buffer;
|
||||||
|
for (uint32_t i = 0; i < NumLumps; i++)
|
||||||
|
{
|
||||||
|
buffer.Resize(fileinfo[i].filelen);
|
||||||
|
fseek(f, fileinfo[i].filepos, SEEK_SET);
|
||||||
|
if (buffer.Size() != fread(&buffer[0], 1, buffer.Size(), f)) return;
|
||||||
|
CreatePath(fileinfo[i].name);
|
||||||
|
FILE* fout = fopen(fileinfo[i].name, "wb");
|
||||||
|
if (fout)
|
||||||
|
{
|
||||||
|
fwrite(&buffer[0], 1, fileinfo[i].filelen, fout);
|
||||||
|
fclose(fout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,6 +165,7 @@ const char * CWADFile::GetLumpName(int lump)
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void GrpExtract(const char* filename, FILE* f);
|
void GrpExtract(const char* filename, FILE* f);
|
||||||
|
void PakExtract(const char* filename, FILE* f);
|
||||||
void RffExtract(const char* filename, FILE* f);
|
void RffExtract(const char* filename, FILE* f);
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -207,6 +208,11 @@ void OpenMainWad(char *filename)
|
||||||
GrpExtract(filename, f);
|
GrpExtract(filename, f);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
else if (memcmp(type, "PACK", 4) == 0)
|
||||||
|
{
|
||||||
|
PakExtract(filename, f);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
else if (!memcmp(type, "RFF\x1a", 4))
|
else if (!memcmp(type, "RFF\x1a", 4))
|
||||||
{
|
{
|
||||||
RffExtract(filename, f);
|
RffExtract(filename, f);
|
||||||
|
|
Loading…
Reference in a new issue