mirror of
https://github.com/ZDoom/wadext.git
synced 2024-11-21 11:21:19 +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);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
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 PakExtract(const char* filename, FILE* f);
|
||||
void RffExtract(const char* filename, FILE* f);
|
||||
|
||||
//==========================================================================
|
||||
|
@ -207,6 +208,11 @@ void OpenMainWad(char *filename)
|
|||
GrpExtract(filename, f);
|
||||
exit(1);
|
||||
}
|
||||
else if (memcmp(type, "PACK", 4) == 0)
|
||||
{
|
||||
PakExtract(filename, f);
|
||||
exit(1);
|
||||
}
|
||||
else if (!memcmp(type, "RFF\x1a", 4))
|
||||
{
|
||||
RffExtract(filename, f);
|
||||
|
|
Loading…
Reference in a new issue