.gz support should work within pak files

This commit is contained in:
Bill Currie 2002-01-03 21:05:07 +00:00
parent 50df3fffe0
commit e72220faf0

View file

@ -18,6 +18,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "qcommon.h" #include "qcommon.h"
// define this to dissalow any data but the demo pak file // define this to dissalow any data but the demo pak file
@ -191,6 +196,45 @@ int Developer_searchpath (int who)
} }
QFile *
FS_OpenRead (const char *path, int offs, int len, int zip, int *size)
{
int fd = open (path, O_RDONLY);
unsigned char id[2];
unsigned char len_bytes[4];
if (fd == -1)
return 0;
if (offs < 0 || len < 0) {
// normal file
offs = 0;
len = lseek (fd, 0, SEEK_END);
lseek (fd, 0, SEEK_SET);
}
lseek (fd, offs, SEEK_SET);
if (zip) {
read (fd, id, 2);
if (id[0] == 0x1f && id[1] == 0x8b) {
lseek (fd, offs + len - 4, SEEK_SET);
read (fd, len_bytes, 4);
len = ((len_bytes[3] << 24)
| (len_bytes[2] << 16)
| (len_bytes[1] << 8)
| (len_bytes[0]));
}
}
lseek (fd, offs, SEEK_SET);
*size = len;
#ifdef WIN32
setmode (fd, O_BINARY);
#endif
if (zip)
return Qdopen (fd, "rbz");
else
return Qdopen (fd, "rb");
}
/* /*
=========== ===========
FS_FOpenFile FS_FOpenFile
@ -202,14 +246,24 @@ a seperate file.
=========== ===========
*/ */
int file_from_pak = 0; int file_from_pak = 0;
#ifndef NO_ADDONS
int FS_FOpenFile (char *filename, QFile **file) int _FS_FOpenFile (char *filename, QFile **file, char *foundname, int zip)
{ {
searchpath_t *search; searchpath_t *search;
char netpath[MAX_OSPATH]; char netpath[MAX_OSPATH];
pack_t *pak; pack_t *pak;
int i; int i;
filelink_t *link; filelink_t *link;
int size;
#ifdef HAVE_ZLIB
char gzfilename[MAX_OSPATH];
int filenamelen;
filenamelen = strlen (filename);
strncpy (gzfilename, filename, sizeof (gzfilename));
strncat (gzfilename, ".gz", sizeof (gzfilename) - strlen (gzfilename));
#endif
file_from_pak = 0; file_from_pak = 0;
@ -219,11 +273,17 @@ int FS_FOpenFile (char *filename, QFile **file)
if (!strncmp (filename, link->from, link->fromlength)) if (!strncmp (filename, link->from, link->fromlength))
{ {
Com_sprintf (netpath, sizeof(netpath), "%s%s",link->to, filename+link->fromlength); Com_sprintf (netpath, sizeof(netpath), "%s%s",link->to, filename+link->fromlength);
*file = Qopen (netpath, "rbz"); *file = FS_OpenRead (netpath, -1, -1, zip, &size);
#ifdef HAVE_ZLIB
if (!*file) {
Com_sprintf (netpath, sizeof(netpath), "%s%s.gz",link->to, filename+link->fromlength);
*file = FS_OpenRead (netpath, -1, -1, zip, &size);
}
#endif
if (*file) if (*file)
{ {
Com_DPrintf ("link file: %s\n",netpath); Com_DPrintf ("link file: %s\n",netpath);
return FS_filelength (*file); return size;
} }
return -1; return -1;
} }
@ -240,16 +300,22 @@ int FS_FOpenFile (char *filename, QFile **file)
// look through all the pak file elements // look through all the pak file elements
pak = search->pack; pak = search->pack;
for (i=0 ; i<pak->numfiles ; i++) for (i=0 ; i<pak->numfiles ; i++)
if (!Q_strcasecmp (pak->files[i].name, filename)) if (!Q_strcasecmp (pak->files[i].name, filename)
#ifdef HAVE_ZLIB
|| !Q_strcasecmp (pak->files[i].name, gzfilename)
#endif
)
{ // found it! { // found it!
file_from_pak = 1; file_from_pak = 1;
Com_DPrintf ("PackFile: %s : %s\n",pak->filename, filename); Com_DPrintf ("PackFile: %s : %s\n",pak->filename, filename);
// open a new file on the pakfile // open a new file on the pakfile
*file = Qopen (pak->filename, "rb"); strncpy (foundname, pak->files[i].name, MAX_OSPATH);
*file = FS_OpenRead (pak->files[i].name,
pak->files[i].filepos,
pak->files[i].filelen, zip, &size);
if (!*file) if (!*file)
Com_Error (ERR_FATAL, "Couldn't reopen %s", pak->filename); Com_Error (ERR_FATAL, "Couldn't reopen %s", pak->filename);
Qseek (*file, pak->files[i].filepos, SEEK_SET); return size;
return pak->files[i].filelen;
} }
} }
else else
@ -258,13 +324,19 @@ int FS_FOpenFile (char *filename, QFile **file)
Com_sprintf (netpath, sizeof(netpath), "%s/%s",search->filename, filename); Com_sprintf (netpath, sizeof(netpath), "%s/%s",search->filename, filename);
*file = Qopen (netpath, "rbz"); *file = FS_OpenRead (netpath, -1, -1, zip, &size);
#ifdef HAVE_ZLIB
if (!*file) {
Com_sprintf (netpath, sizeof(netpath), "%s/%s.gz",search->filename, filename);
*file = FS_OpenRead (netpath, -1, -1, zip, &size);
}
#endif
if (!*file) if (!*file)
continue; continue;
Com_DPrintf ("FindFile: %s\n",netpath); Com_DPrintf ("FindFile: %s\n",netpath);
return FS_filelength (*file); return size;
} }
} }
@ -275,64 +347,14 @@ int FS_FOpenFile (char *filename, QFile **file)
return -1; return -1;
} }
#else int
FS_FOpenFile (char *filename, QFile **gzfile)
// this is just for demos to prevent add on hacking
int FS_FOpenFile (char *filename, QFile **file)
{ {
searchpath_t *search; char foundname[MAX_OSPATH];
char netpath[MAX_OSPATH];
pack_t *pak;
int i;
file_from_pak = 0; return _FS_FOpenFile (filename, gzfile, foundname, 1);
// get config from directory, everything else from pak
if (!strcmp(filename, "config.cfg") || !strncmp(filename, "players/", 8))
{
Com_sprintf (netpath, sizeof(netpath), "%s/%s",FS_Gamedir(), filename);
*file = Qopen (netpath, "rbz");
if (!*file)
return -1;
Com_DPrintf ("FindFile: %s\n",netpath);
return FS_filelength (*file);
}
for (search = fs_searchpaths ; search ; search = search->next)
if (search->pack)
break;
if (!search)
{
*file = NULL;
return -1;
}
pak = search->pack;
for (i=0 ; i<pak->numfiles ; i++)
if (!Q_strcasecmp (pak->files[i].name, filename))
{ // found it!
file_from_pak = 1;
Com_DPrintf ("PackFile: %s : %s\n",pak->filename, filename);
// open a new file on the pakfile
*file = Qopen (pak->filename, "rb");
if (!*file)
Com_Error (ERR_FATAL, "Couldn't reopen %s", pak->filename);
Qseek (*file, pak->files[i].filepos, SEEK_SET);
return pak->files[i].filelen;
}
Com_DPrintf ("FindFile: can't find %s\n", filename);
*file = NULL;
return -1;
} }
#endif
/* /*
================= =================