100 lines
3 KiB
Text
100 lines
3 KiB
Text
#include "quakedef.h"
|
|
#include "pk3.h"
|
|
|
|
typedef struct
|
|
{
|
|
char name[MAX_QPATH];
|
|
int filepos, filelen;
|
|
} packfile_t;
|
|
|
|
typedef struct pack_s
|
|
{
|
|
char filename[MAX_OSPATH];
|
|
int handle;
|
|
int numfiles;
|
|
packfile_t *files;
|
|
} pack_t;
|
|
|
|
#define MAX_FILES_IN_PACK 2048
|
|
|
|
/*
|
|
=================
|
|
COM_LoadZipFile
|
|
|
|
Takes an explicit (not game tree related) path to a zip file.
|
|
|
|
Loads the header and directory, adding the files at the beginning
|
|
of the list so they override previous pack files.
|
|
|
|
Only unpacked zip's are supported because of the way PACK's are handled.
|
|
=================
|
|
*/
|
|
#define LongBytes(a) *(int *)a
|
|
#define ShortBytes(a) *(short *)a
|
|
pack_t *COM_LoadZipFile (char *packfile)
|
|
{
|
|
zipheader_t header;
|
|
int packhandle;
|
|
int i = 0, size;
|
|
packfile_t *newfiles;
|
|
int numpackfiles = 0;
|
|
pack_t *pack;
|
|
zipfileheader_t *info;
|
|
unsigned short crc;
|
|
|
|
if (Sys_FileOpenRead (packfile, &packhandle) == -1)
|
|
return NULL;
|
|
Sys_FileRead (packhandle, (void *)&header, zipheadersize);
|
|
if (header.ident != ZIPIDHEADER)
|
|
Sys_Error ("%s is not a Zip or PK3file", packfile);
|
|
size = zipheadersize + header.filenamelen;// + header.extralen;
|
|
Sys_FileSeek (packhandle, size);
|
|
|
|
while(1)
|
|
{
|
|
unsigned char *ident;
|
|
zipfileheader_t tmp;
|
|
Sys_FileRead (packhandle, (void *)&tmp, sizeof(tmp));
|
|
if(tmp.ident == ZIPFILEENDHEADER)
|
|
continue;
|
|
numpackfiles++;
|
|
size += sizeof(zipfileheader_t) + tmp.extralen + tmp.filenamelen + tmp.commentlen;
|
|
Sys_FileSeek (packhandle, size);
|
|
|
|
ident = (char *)&tmp.ident;
|
|
Sys_Error("%i %i %i", tmp.filenamelen, tmp.extralen, tmp.commentlen);
|
|
Sys_Error("FILE # : %i\n IDENT : %i\n IDENT : %.8s\n IDENT : %i %i %i %i %i %i %i %i\n\nBASE IDENTS: %i & %i",
|
|
numpackfiles, tmp.ident,
|
|
ident, //ident[0],ident[1],ident[2],ident[3],ident[4],ident[5],ident[6],ident[7],
|
|
(int)ident[0],(int)ident[1],(int)ident[2],(int)ident[3],(int)ident[4],(int)ident[5],(int)ident[6],(int)ident[7],
|
|
ZIPFILEENDHEADER, ZIPFILEIDHEADER);
|
|
}
|
|
Sys_Error("passed!");
|
|
|
|
if (numpackfiles > MAX_FILES_IN_PACK)
|
|
Sys_Error ("%s has %i files", packfile, numpackfiles);
|
|
|
|
newfiles = Hunk_AllocName (numpackfiles * sizeof(packfile_t), "packfile");
|
|
|
|
Sys_FileSeek (packhandle, zipheadersize + header.filenamelen + header.extralen);
|
|
info = malloc(sizeof(zipfileheader_t) * numpackfiles);
|
|
Sys_FileRead (packhandle, info, sizeof(zipfileheader_t) * numpackfiles);
|
|
|
|
// parse the directory
|
|
for (i=0 ; i<numpackfiles ; i++)
|
|
{
|
|
strcpy (newfiles[i].name, (char *)&info[i] + sizeof(zipfileheader_t));
|
|
newfiles[i].filepos = LongBytes(info[i].offset);
|
|
newfiles[i].filelen = LongBytes(info[i].compressedsize);
|
|
}
|
|
|
|
pack = Hunk_Alloc (sizeof (pack_t));
|
|
strcpy (pack->filename, packfile);
|
|
pack->handle = packhandle;
|
|
pack->numfiles = numpackfiles;
|
|
pack->files = newfiles;
|
|
|
|
Con_Printf ("Added packfile %s (%i files)\n", packfile, numpackfiles);
|
|
return pack;
|
|
}
|
|
|