mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
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:
parent
337deae4ae
commit
acf9ce392c
11 changed files with 116 additions and 147 deletions
|
@ -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
|
||||
|
|
|
@ -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
62
include/QF/pakfile.h
Normal 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
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
Loading…
Reference in a new issue