Browse Source

filesystem: zip: pk3 support

pull/2/head
Mr0maks 6 years ago
parent
commit
3c0a34926a
  1. 79
      engine/common/filesystem.c
  2. 76
      engine/common/filesystem.h

79
engine/common/filesystem.c

@ -644,7 +644,6 @@ static zipfile_t *FS_AddFileToZip( const char *name, zip_t *zip, fs_offset_t off @@ -644,7 +644,6 @@ static zipfile_t *FS_AddFileToZip( const char *name, zip_t *zip, fs_offset_t off
static zip_t *FS_LoadZip( const char *zipfile, int *error )
{
zip_header_t header;
int numpackfiles = 0;
zip_cdf_header_t header_cdf;
zip_header_eocd_t header_eocd;
@ -658,18 +657,18 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error ) @@ -658,18 +657,18 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
zip->handle = FS_Open( zipfile, "rb", true );
#ifndef _WIN32
if ( !zip->handle )
if( !zip->handle )
{
const char *fzipfile = FS_FixFileCase( zipfile );
if (fzipfile != zipfile)
if( fzipfile != zipfile )
zip->handle = FS_Open( fzipfile, "rb", true );
}
#endif
if ( !zip->handle )
if( !zip->handle )
{
Con_Reportf( "%s couldn't open\n", zipfile );
if (error)
if( error )
*error = ZIP_LOAD_COULDNT_OPEN;
Zip_Close( zip );
return NULL;
@ -678,7 +677,7 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error ) @@ -678,7 +677,7 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
if( FS_FileLength( zip->handle ) > UINT_MAX )
{
Con_Reportf( "%s bigger than 4GB.\n", zipfile );
if (error)
if( error )
*error = ZIP_LOAD_COULDNT_OPEN;
Zip_Close( zip );
return NULL;
@ -686,17 +685,17 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error ) @@ -686,17 +685,17 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
FS_Read( zip->handle, (void *)&signature, sizeof( uint ) );
if ( signature == ZIP_HEADER_EOCD )
if( signature == ZIP_HEADER_EOCD )
{
Con_Reportf( "%s has no files. Ignored.\n", zipfile );
if (error)
if(error)
*error = ZIP_LOAD_NO_FILES;
Zip_Close( zip );
return NULL;
}
if ( signature != ZIP_HEADER_LF ) {
if( signature != ZIP_HEADER_LF ) {
Con_Reportf( "%s is not a zip file. Ignored.\n", zipfile );
if (error)
if( error )
*error = ZIP_LOAD_BAD_HEADER;
Zip_Close( zip );
return NULL;
@ -711,11 +710,11 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error ) @@ -711,11 +710,11 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
FS_Seek( zip->handle, filepos, SEEK_SET );
FS_Read( zip->handle, (void *)&signature, sizeof( signature ) );
if (signature == ZIP_HEADER_EOCD) break;
if( signature == ZIP_HEADER_EOCD ) break;
filepos -= sizeof( char ); // step back one byte
}
if (ZIP_HEADER_EOCD != signature)
if( ZIP_HEADER_EOCD != signature )
{
Con_Reportf( "Cannot find EOCD in %s. Zip file corrupted.\n", zipfile );
Zip_Close( zip );
@ -736,15 +735,15 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error ) @@ -736,15 +735,15 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
{
FS_Read( zip->handle, (void *)&header_cdf, sizeof( header_cdf ) );
if (header_cdf.signature != ZIP_HEADER_CDF)
if( header_cdf.signature != ZIP_HEADER_CDF )
{
Con_Reportf( "CDF signature mismatch in %s. Zip file corrupted.\n", zipfile );
Zip_Close( zip );
return NULL;
}
if ( header_cdf.uncompressed_size && header_cdf.filename_len )
{
if( header_cdf.uncompressed_size && header_cdf.filename_len )
{
char *filename = malloc( header_cdf.filename_len + 1 );
memset( filename, '\0', header_cdf.filename_len + 1 );
@ -759,14 +758,14 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error ) @@ -759,14 +758,14 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
//Con_Reportf( "ZIP File name: %s .\n", info[numpackfiles].name );
numpackfiles++;
}
}
else
FS_Seek( zip->handle, header_cdf.filename_len, SEEK_CUR );
if ( header_cdf.extrafield_len )
if( header_cdf.extrafield_len )
FS_Seek( zip->handle, header_cdf.extrafield_len, SEEK_CUR );
if ( header_cdf.file_commentary_len )
if( header_cdf.file_commentary_len )
FS_Seek( zip->handle, header_cdf.file_commentary_len, SEEK_CUR );
}
@ -776,10 +775,10 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error ) @@ -776,10 +775,10 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
zip->numfiles = 0;
zip->files = (zipfile_t *)Mem_Calloc( fs_mempool, sizeof( zipfile_t ) * numpackfiles );
for(int i = 0; i < numpackfiles; i++ )
for( int i = 0; i < numpackfiles; i++ )
FS_AddFileToZip( info[i].name, zip, info[i].offset, info[i].size, info[i].compressed_size );
if ( error ) *error = ZIP_LOAD_OK;
if( error ) *error = ZIP_LOAD_OK;
Mem_Free( info );
return zip;
@ -787,7 +786,7 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error ) @@ -787,7 +786,7 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
void Zip_Close( zip_t *zip )
{
if ( !zip )
if( !zip )
return;
Mem_FreePool( &zip->mempool );
@ -818,19 +817,19 @@ static byte *Zip_LoadFile( const char *path, fs_offset_t *sizeptr, qboolean game @@ -818,19 +817,19 @@ static byte *Zip_LoadFile( const char *path, fs_offset_t *sizeptr, qboolean game
FS_Read( search->zip->handle, (void*)&header, sizeof( header ) );
if (header.signature != ZIP_HEADER_LF)
if(header.signature != ZIP_HEADER_LF)
{
Con_Reportf( S_ERROR "Zip_LoadFile: %s signature error\n", file->name );
return NULL;
}
if (header.compression_flags == ZIP_COMPRESSION_NO_COMPRESSION)
if(header.compression_flags == ZIP_COMPRESSION_NO_COMPRESSION)
{
if( header.filename_len )
FS_Seek( search->zip->handle, header.filename_len, SEEK_CUR );
if (header.extrafield_len)
if( header.extrafield_len )
FS_Seek( search->zip->handle, header.extrafield_len, SEEK_CUR );
byte *buffer = Mem_Malloc( search->zip->mempool, file->size + 1 );
@ -855,12 +854,12 @@ static byte *Zip_LoadFile( const char *path, fs_offset_t *sizeptr, qboolean game @@ -855,12 +854,12 @@ static byte *Zip_LoadFile( const char *path, fs_offset_t *sizeptr, qboolean game
//Con_Reportf( "ZIP %s load file %s with size %lu\n", search->zip->filename, file->name, file->size );
if (sizeptr) *sizeptr = file->size;
if( sizeptr ) *sizeptr = file->size;
return buffer;
}
#ifdef XASH_ZLIB
if(header.compression_flags == ZIP_COMPRESSION_DEFLATED) {
if( header.compression_flags == ZIP_COMPRESSION_DEFLATED ) {
if( header.filename_len )
FS_Seek( search->zip->handle, header.filename_len, SEEK_CUR );
@ -1059,7 +1058,7 @@ qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int @@ -1059,7 +1058,7 @@ qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int
if( already_loaded ) *already_loaded = false;
if( !Q_stricmp( ext, "zip" ))
if( !Q_stricmp( ext, "zip" ) || !Q_stricmp( ext, "pk3" ) )
zip = FS_LoadZip( zipfile, &errorcode );
if( zip )
@ -1125,13 +1124,13 @@ void FS_AddGameDirectory( const char *dir, uint flags ) @@ -1125,13 +1124,13 @@ void FS_AddGameDirectory( const char *dir, uint flags )
// add any Zip package in the directory
for( i = 0; i < list.numstrings; i++ )
{
if( !Q_stricmp( COM_FileExtension( list.strings[i] ), "zip" ))
{
Q_sprintf( fullpath, "%s%s", dir, list.strings[i] );
FS_AddZip_Fullpath( fullpath, NULL, flags );
}
}
{
if( !Q_stricmp( COM_FileExtension( list.strings[i] ), "zip" ) || !Q_stricmp( COM_FileExtension( list.strings[i] ), "pk3" ))
{
Q_sprintf( fullpath, "%s%s", dir, list.strings[i] );
FS_AddZip_Fullpath( fullpath, NULL, flags );
}
}
stringlistfreecontents( &list );
FS_AllowDirectPaths( false );
@ -1231,10 +1230,10 @@ void FS_ClearSearchPath( void ) @@ -1231,10 +1230,10 @@ void FS_ClearSearchPath( void )
W_Close( search->wad );
}
if (search->zip)
{
Zip_Close(search->zip);
}
if(search->zip)
{
Zip_Close(search->zip);
}
Mem_Free( search );
}
@ -2907,7 +2906,7 @@ byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamediro @@ -2907,7 +2906,7 @@ byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamediro
{
buf = W_LoadFile( path, &filesize, gamedironly );
if (!buf)
if( !buf )
buf = Zip_LoadFile(path, &filesize, gamedironly);
}
@ -3177,7 +3176,7 @@ int FS_FileTime( const char *filename, qboolean gamedironly ) @@ -3177,7 +3176,7 @@ int FS_FileTime( const char *filename, qboolean gamedironly )
return search->pack->filetime;
else if( search->wad ) // grab wad filetime
return search->wad->filetime;
else if (search->zip)
else if( search->zip )
return search->zip->filetime;
else if( pack_ind < 0 )
{

76
engine/common/filesystem.h

@ -139,16 +139,16 @@ typedef struct @@ -139,16 +139,16 @@ typedef struct
#pragma pack( 1 )
typedef struct zip_header_s
{
uint signature; // little endian ZIP_HEADER
u_int16_t version; // version of pkzip need to unpack
u_int16_t flags; // flags (16 bits == 16 flags)
u_int16_t compression_flags; // compression flags (bits)
uint dos_date; // file modification time and file modification date
uint crc32; //crc32
uint compressed_size;
uint uncompressed_size;
u_int16_t filename_len;
u_int16_t extrafield_len;
uint signature; // little endian ZIP_HEADER
u_int16_t version; // version of pkzip need to unpack
u_int16_t flags; // flags (16 bits == 16 flags)
u_int16_t compression_flags; // compression flags (bits)
uint dos_date; // file modification time and file modification date
uint crc32; //crc32
uint compressed_size;
uint uncompressed_size;
u_int16_t filename_len;
u_int16_t extrafield_len;
} zip_header_t;
#pragma pack( )
@ -161,46 +161,46 @@ typedef struct zip_header_s @@ -161,46 +161,46 @@ typedef struct zip_header_s
#pragma pack( 1 )
typedef struct zip_header_extra_s
{
uint signature; // ZIP_HEADER_SPANNED
uint crc32;
uint compressed_size;
uint uncompressed_size;
uint signature; // ZIP_HEADER_SPANNED
uint crc32;
uint compressed_size;
uint uncompressed_size;
} zip_header_extra_t;
#pragma pack( )
#pragma pack( 1 )
typedef struct zip_cdf_header_s
{
uint signature;
u_int16_t version;
u_int16_t version_need;
u_int16_t generalPurposeBitFlag;
u_int16_t flags;
u_int16_t modification_time;
u_int16_t modification_date;
uint crc32;
uint compressed_size;
uint uncompressed_size;
u_int16_t filename_len;
u_int16_t extrafield_len;
u_int16_t file_commentary_len;
u_int16_t disk_start;
u_int16_t internal_attr;
uint external_attr;
uint local_header_offset;
uint signature;
u_int16_t version;
u_int16_t version_need;
u_int16_t generalPurposeBitFlag;
u_int16_t flags;
u_int16_t modification_time;
u_int16_t modification_date;
uint crc32;
uint compressed_size;
uint uncompressed_size;
u_int16_t filename_len;
u_int16_t extrafield_len;
u_int16_t file_commentary_len;
u_int16_t disk_start;
u_int16_t internal_attr;
uint external_attr;
uint local_header_offset;
} zip_cdf_header_t;
#pragma pack ( )
#pragma pack( 1 )
typedef struct zip_header_eocd_s
{
u_int16_t disk_number;
u_int16_t start_disk_number;
u_int16_t number_central_directory_record;
u_int16_t total_central_directory_record;
uint size_of_central_directory;
uint central_directory_offset;
u_int16_t commentary_len;
u_int16_t disk_number;
u_int16_t start_disk_number;
u_int16_t number_central_directory_record;
u_int16_t total_central_directory_record;
uint size_of_central_directory;
uint central_directory_offset;
u_int16_t commentary_len;
} zip_header_eocd_t;
#pragma pack( )

Loading…
Cancel
Save