move pakfile.[ch] into libQFutil and make quakefs.c use it instead of its

own code. This also removes the evil pak file count limit :)
This commit is contained in:
Bill Currie 2002-07-21 06:11:28 +00:00
parent 337deae4ae
commit acf9ce392c
11 changed files with 116 additions and 147 deletions

View file

@ -4,8 +4,8 @@ includedir = $(prefix)/include/QF
include_HEADERS = bspfile.h cdaudio.h checksum.h clip_hull.h cmd.h \
console.h crc.h csqc.h cvar.h dstring.h draw.h gcc_attr.h hash.h hl.h \
in_event.h info.h input.h joystick.h keys.h link.h locs.h \
mathlib.h mdfour.h model.h modelgen.h msg.h pak.h pcx.h plugin.h \
pr_comp.h pr_debug.h pr_obj.h progs.h qargs.h qdefs.h qendian.h qfplist.h \
qtypes.h render.h screen.h sizebuf.h skin.h sound.h spritegn.h \
mathlib.h mdfour.h model.h modelgen.h msg.h pak.h pakfile.h pcx.h \
plugin.h pr_comp.h pr_debug.h pr_obj.h progs.h qargs.h qdefs.h qendian.h \
qfplist.h qtypes.h render.h screen.h sizebuf.h skin.h sound.h spritegn.h \
sys.h teamplay.h texture.h tga.h uint32.h va.h \
ver_check.h vfile.h vfs.h vid.h wad.h zone.h

View file

@ -45,6 +45,4 @@ typedef struct {
int dirlen;
} dpackheader_t;
#define MAX_FILES_IN_PACK 2048
#endif//__qf_pak_h

62
include/QF/pakfile.h Normal file
View file

@ -0,0 +1,62 @@
/*
#FILENAME#
#DESCRIPTION#
Copyright (C) 2002 #AUTHOR#
Author: #AUTHOR#
Date: #DATE#
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifndef __QF_pakfile_h
#define __QF_pakfile_h
#include "QF/vfile.h"
#include "QF/hash.h"
#include "QF/pak.h"
typedef struct pack_s {
char *filename;
VFile *handle;
int numfiles;
int files_size;
dpackfile_t *files;
hashtab_t *file_hash;
dpackheader_t header;
int modified;
int old_numfiles;
int pad;
} pack_t;
pack_t *pack_new (const char *name);
void pack_del (pack_t *pack);
pack_t *pack_open (const char *name);
void pack_close (pack_t *pack);
pack_t *pack_create (const char *name);
int pack_add (pack_t *pack, const char *filename);
int pack_extract (pack_t *pack, dpackfile_t *pf);
dpackfile_t *pack_find_file (pack_t *pack, const char *filename);
#endif//__QF_pakfile_h

View file

@ -38,26 +38,9 @@
#define MAX_OSPATH 128 // max length of a filesystem pathname
/*
In-memory pack file structs
*/
typedef struct {
char name[MAX_QPATH];
int filepos, filelen;
} packfile_t;
typedef struct pack_s {
char filename[MAX_OSPATH];
VFile *handle;
int numfiles;
packfile_t *files;
struct hashtab_s *file_hash;
} pack_t;
typedef struct searchpath_s {
char filename[MAX_OSPATH];
pack_t *pack; // only one of filename / pack will be used
struct pack_s *pack; // only one of filename / pack will be used
struct searchpath_s *next;
} searchpath_t;

View file

@ -70,6 +70,7 @@ static const char rcsid[] =
#include "QF/console.h"
#include "QF/cvar.h"
#include "QF/hash.h"
#include "QF/pakfile.h"
#include "QF/qargs.h"
#include "QF/qendian.h"
#include "QF/qtypes.h"

View file

@ -28,7 +28,7 @@ libQFutil_la_DEPENDENCIES= libasm.la
libQFutil_la_SOURCES= \
buildnum.c checksum.c cmd.c crc.c cvar.c dstring.c exp.c fendian.c \
getopt.c getopt1.c hash.c info.c link.c mathlib.c mdfour.c msg.c ops.c \
pcx.c plugin.c qargs.c qendian.c qfplist.c quakefs.c quakeio.c sizebuf.c \
string.c sys.c tga.c va.c ver_check.c wad.c zone.c $(fnmatch)
pakfile.c pcx.c plugin.c qargs.c qendian.c qfplist.c quakefs.c quakeio.c \
sizebuf.c string.c sys.c tga.c va.c ver_check.c wad.c zone.c $(fnmatch)
EXTRA_DIST= $(asm_src) $(fnmatch_src)

View file

@ -8,9 +8,8 @@
#include <fcntl.h>
#include <errno.h>
#include <QF/qendian.h>
#include "pakfile.h"
#include "QF/pakfile.h"
#include "QF/qendian.h"
#ifdef _WIN32
void *alloca(size_t size);
@ -49,7 +48,7 @@ pack_del (pack_t *pack)
if (pack->files)
free (pack->files);
if (pack->handle)
fclose (pack->handle);
Qclose (pack->handle);
if (pack->filename)
free (pack->filename);
if (pack->file_hash)
@ -65,11 +64,11 @@ pack_open (const char *name)
if (!pack)
return 0;
pack->handle = fopen (name, "rb");
pack->handle = Qopen (name, "rb");
if (!pack->handle) {
goto error;
}
if (fread (&pack->header, 1, sizeof (pack->header), pack->handle)
if (Qread (pack->handle, &pack->header, sizeof (pack->header))
!= sizeof (pack->header)) {
fprintf (stderr, "%s: not a pack file", name);
goto error;
@ -90,8 +89,8 @@ pack_open (const char *name)
fprintf (stderr, "out of memory\n");
goto error;
}
fseek (pack->handle, pack->header.dirofs, SEEK_SET);
fread (pack->files, pack->numfiles, sizeof (pack->files[0]), pack->handle);
Qseek (pack->handle, pack->header.dirofs, SEEK_SET);
Qread (pack->handle, pack->files, pack->numfiles * sizeof (pack->files[0]));
for (i = 0; i < pack->numfiles; i++) {
pack->files[i].filepos = LittleLong (pack->files[i].filepos);
@ -112,14 +111,14 @@ pack_create (const char *name)
if (!pack)
return 0;
pack->handle = fopen (name, "wb");
pack->handle = Qopen (name, "wb");
if (!pack->handle) {
pack_del (pack);
return 0;
}
strncpy (pack->header.id, "PACK", sizeof (pack->header.id));
fwrite (&pack->header, 1, sizeof (pack->header), pack->handle);
Qwrite (pack->handle, &pack->header, sizeof (pack->header));
return pack;
}
@ -131,24 +130,24 @@ pack_close (pack_t *pack)
if (pack->modified) {
if (pack->numfiles > pack->old_numfiles) {
fseek (pack->handle, 0, SEEK_END);
pack->header.dirofs = ftell (pack->handle);
Qseek (pack->handle, 0, SEEK_END);
pack->header.dirofs = Qtell (pack->handle);
}
for (i = 0; i < pack->numfiles; i++) {
pack->files[i].filepos = LittleLong (pack->files[i].filepos);
pack->files[i].filelen = LittleLong (pack->files[i].filelen);
}
fseek (pack->handle, pack->header.dirofs, SEEK_SET);
fwrite (pack->files, pack->numfiles,
sizeof (pack->files[0]), pack->handle);
Qseek (pack->handle, pack->header.dirofs, SEEK_SET);
Qwrite (pack->handle, pack->files,
pack->numfiles * sizeof (pack->files[0]));
pack->header.dirlen = pack->numfiles * sizeof (pack->files[0]);
pack->header.dirofs = LittleLong (pack->header.dirofs);
pack->header.dirlen = LittleLong (pack->numfiles
* sizeof (pack->files[0]));
fseek (pack->handle, 0, SEEK_SET);
fwrite (&pack->header, 1, sizeof (pack->header), pack->handle);
Qseek (pack->handle, 0, SEEK_SET);
Qwrite (pack->handle, &pack->header, sizeof (pack->header));
fseek (pack->handle, 0, SEEK_END);
Qseek (pack->handle, 0, SEEK_END);
}
pack_del (pack);
}
@ -157,7 +156,7 @@ int
pack_add (pack_t *pack, const char *filename)
{
dpackfile_t *pf;
FILE *file;
VFile *file;
char buffer[16384];
int bytes;
@ -167,11 +166,7 @@ pack_add (pack_t *pack, const char *filename)
if (pack->numfiles == pack->files_size) {
dpackfile_t *f;
if (pack->files_size == MAX_FILES_IN_PACK)
return -1;
pack->files_size += 64;
if (pack->files_size > MAX_FILES_IN_PACK)
pack->files_size = MAX_FILES_IN_PACK;
f = realloc (pack->files, pack->files_size * sizeof (dpackfile_t));
if (!f)
@ -179,7 +174,7 @@ pack_add (pack_t *pack, const char *filename)
pack->files = f;
}
file = fopen (filename, "rb");
file = Qopen (filename, "rb");
if (!file)
return -1;
@ -194,17 +189,17 @@ pack_add (pack_t *pack, const char *filename)
strncpy (pf->name, filename, sizeof (pf->name));
pf->name[sizeof (pf->name) - 1] = 0;
fseek (pack->handle, 0, SEEK_END);
pf->filepos = ftell (pack->handle);
Qseek (pack->handle, 0, SEEK_END);
pf->filepos = Qtell (pack->handle);
pf->filelen = 0;
while ((bytes = fread (buffer, 1, sizeof (buffer), file))) {
fwrite (buffer, 1, bytes, pack->handle);
while ((bytes = Qread (file, buffer, sizeof (buffer)))) {
Qwrite (pack->handle, buffer, bytes);
pf->filelen += bytes;
}
fclose (file);
Qclose (file);
if (pack->pad && pf->filelen & 3) {
static char buf[4];
fwrite (buf, 1, 4 - (pf->filelen & 3), pack->handle);
Qwrite (pack->handle, buf, 4 - (pf->filelen & 3));
}
Hash_Add (pack->file_hash, pf);
return 0;
@ -239,23 +234,29 @@ pack_extract (pack_t *pack, dpackfile_t *pf)
const char *name = pf->name;
int count;
int len;
FILE *file;
VFile *file;
char buffer[16384];
if (make_parents (name) == -1)
return -1;
if (!(file = fopen (name, "wb")))
if (!(file = Qopen (name, "wb")))
return -1;
fseek (pack->handle, pf->filepos, SEEK_SET);
Qseek (pack->handle, pf->filepos, SEEK_SET);
len = pf->filelen;
while (len) {
count = len;
if (count > sizeof (buffer))
count = sizeof (buffer);
count = fread (buffer, 1, count, pack->handle);
fwrite (buffer, 1, count, file);
count = Qread (pack->handle, buffer, count);
Qwrite (file, buffer, count);
len -= count;
}
fclose (file);
Qclose (file);
return 0;
}
dpackfile_t *
pack_find_file (pack_t *pack, const char *filename)
{
return Hash_Find (pack->file_hash, filename);
}

View file

@ -70,6 +70,7 @@ static const char rcsid[] =
#include "QF/cvar.h"
#include "QF/hash.h"
#include "QF/pak.h"
#include "QF/pakfile.h"
#include "QF/qargs.h"
#include "QF/qendian.h"
#include "QF/qtypes.h"
@ -409,10 +410,9 @@ open_file (searchpath_t *search, const char *filename, VFile **gzfile,
// is the element a pak file?
if (search->pack) {
packfile_t *packfile;
dpackfile_t *packfile;
packfile = (packfile_t *) Hash_Find (search->pack->file_hash,
filename);
packfile = pack_find_file (search->pack, filename);
if (packfile) {
Sys_DPrintf ("PackFile: %s : %s\n", search->pack->filename,
packfile->name);
@ -586,14 +586,6 @@ COM_LoadStackFile (const char *path, void *buffer, int bufsize)
return buf;
}
static const char *
pack_get_key (void *_p, void *unused)
{
packfile_t *p = (packfile_t *) _p;
return p->name;
}
/*
COM_LoadPackFile
@ -605,52 +597,11 @@ pack_get_key (void *_p, void *unused)
pack_t *
COM_LoadPackFile (char *packfile)
{
dpackheader_t header;
int i;
packfile_t *newfiles;
int numpackfiles;
pack_t *pack;
VFile *packhandle;
dpackfile_t info[MAX_FILES_IN_PACK];
hashtab_t *hash;
pack_t *pack = pack_open (packfile);
if (COM_FileOpenRead (packfile, &packhandle) == -1)
return NULL;
Qread (packhandle, &header, sizeof (header));
if (header.id[0] != 'P' || header.id[1] != 'A'
|| header.id[2] != 'C' || header.id[3] != 'K')
Sys_Error ("%s is not a packfile", packfile);
header.dirofs = LittleLong (header.dirofs);
header.dirlen = LittleLong (header.dirlen);
numpackfiles = header.dirlen / sizeof (dpackfile_t);
if (numpackfiles > MAX_FILES_IN_PACK)
Sys_Error ("%s has %i files", packfile, numpackfiles);
newfiles = calloc (1, numpackfiles * sizeof (packfile_t));
hash = Hash_NewTable (1021, pack_get_key, 0, 0);
Qseek (packhandle, header.dirofs, SEEK_SET);
Qread (packhandle, info, header.dirlen);
// parse the directory
for (i = 0; i < numpackfiles; i++) {
strcpy (newfiles[i].name, info[i].name);
newfiles[i].filepos = LittleLong (info[i].filepos);
newfiles[i].filelen = LittleLong (info[i].filelen);
Hash_Add (hash, &newfiles[i]);
}
pack = calloc (1, sizeof (pack_t));
strcpy (pack->filename, packfile);
pack->handle = packhandle;
pack->numfiles = numpackfiles;
pack->files = newfiles;
pack->file_hash = hash;
Sys_Printf ("Added packfile %s (%i files)\n", packfile, numpackfiles);
if (pack)
Sys_Printf ("Added packfile %s (%i files)\n",
packfile, pack->numfiles);
return pack;
}

View file

@ -10,8 +10,8 @@ bin_PROGRAMS= pak
man_MANS= pak.1
pak_SOURCES= pak.c pakfile.c
pak_SOURCES= pak.c
pak_LDADD= $(PAK_LIBS)
pak_DEPENDENCIES= $(PAK_DEPS)
EXTRA_DIST= pak.h pakfile.h pak.1
EXTRA_DIST= pak.h pak.1

View file

@ -46,8 +46,8 @@ static const char rcsid[] =
#include <stdlib.h>
#include <QF/qtypes.h>
#include <QF/pakfile.h>
#include "pakfile.h"
#include "pak.h"
const char *this_program;

View file

@ -1,27 +0,0 @@
#include <stdio.h>
#include <QF/hash.h>
#include <QF/pak.h>
typedef struct pack_s {
char *filename;
FILE *handle;
int numfiles;
int files_size;
dpackfile_t *files;
hashtab_t *file_hash;
dpackheader_t header;
int modified;
int old_numfiles;
int pad;
} pack_t;
pack_t *pack_new (const char *name);
void pack_del (pack_t *pack);
pack_t *pack_open (const char *name);
void pack_close (pack_t *pack);
pack_t *pack_create (const char *name);
int pack_add (pack_t *pack, const char *filename);
int pack_extract (pack_t *pack, dpackfile_t *pf);