From 6cefb63e2e55e3d1baf1c1802b94871b998f1416 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 12 Mar 2002 23:45:36 +0000 Subject: [PATCH] get back to work on creating a good command line pak file util. currently only dumps the file names/sizes and segs if it's used incorrectly, but it's a start. --- include/QF/Makefile.am | 2 +- include/QF/pak.h | 50 ++++++++++++++++++++++++++ libs/util/quakefs.c | 17 +-------- tools/pak/.gitignore | 7 ++++ tools/pak/Makefile | 27 ++++++++++++++ tools/pak/pak.c | 14 ++++++++ tools/pak/pakfile.c | 82 ++++++++++++++++++++++++------------------ tools/pak/pakfile.h | 21 +++++++++++ 8 files changed, 169 insertions(+), 51 deletions(-) create mode 100644 include/QF/pak.h create mode 100644 tools/pak/Makefile create mode 100644 tools/pak/pak.c create mode 100644 tools/pak/pakfile.h diff --git a/include/QF/Makefile.am b/include/QF/Makefile.am index 2733aae92..b17d6f941 100644 --- a/include/QF/Makefile.am +++ b/include/QF/Makefile.am @@ -4,7 +4,7 @@ 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 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 pcx.h plugin.h \ + mathlib.h mdfour.h model.h modelgen.h msg.h pak.h pcx.h plugin.h \ pr_comp.h pr_debug.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 \ diff --git a/include/QF/pak.h b/include/QF/pak.h new file mode 100644 index 000000000..276b2df18 --- /dev/null +++ b/include/QF/pak.h @@ -0,0 +1,50 @@ +/* + pak.h + + Structs for pack files on disk + + Copyright (C) 2001 Bill Currie + + Author: Bill Currie + Date: 2002/3/12 + + 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_pak_h +#define __qf_pak_h + +#define PAK_PATH_LENGTH 56 + +typedef struct { + char name[PAK_PATH_LENGTH]; + int filepos, filelen; +} dpackfile_t; + +typedef struct { + char id[4]; + int dirofs; + int dirlen; +} dpackheader_t; + +#define MAX_FILES_IN_PACK 2048 + +#endif//__qf_pak_h diff --git a/libs/util/quakefs.c b/libs/util/quakefs.c index 0ad2725f7..d44560e30 100644 --- a/libs/util/quakefs.c +++ b/libs/util/quakefs.c @@ -69,6 +69,7 @@ static const char rcsid[] = #include "QF/cmd.h" #include "QF/cvar.h" #include "QF/hash.h" +#include "QF/pak.h" #include "QF/qargs.h" #include "QF/qendian.h" #include "QF/qtypes.h" @@ -119,22 +120,6 @@ cvar_t *fs_skinbase; int com_filesize; -/* - Structs for pack files on disk -*/ -typedef struct { - char name[56]; - int filepos, filelen; -} dpackfile_t; - -typedef struct { - char id[4]; - int dirofs; - int dirlen; -} dpackheader_t; - -#define MAX_FILES_IN_PACK 2048 - char com_gamedir[MAX_OSPATH]; searchpath_t *com_searchpaths; diff --git a/tools/pak/.gitignore b/tools/pak/.gitignore index be2db78c6..c98acc1ef 100644 --- a/tools/pak/.gitignore +++ b/tools/pak/.gitignore @@ -1 +1,8 @@ +*.d +*.la +*.lo +.deps +.libs .vimrc +Makefile.in +pak diff --git a/tools/pak/Makefile b/tools/pak/Makefile new file mode 100644 index 000000000..1d5cbf572 --- /dev/null +++ b/tools/pak/Makefile @@ -0,0 +1,27 @@ +EXE=pak + +MAKEDEPS=$(CC) -MM $(CPPFLAGS) $< | sed -e 's/$*\.o:*/$*\.o $@:/g' > $@ + +CFLAGS+=-Wall -Werror -g -O2 +CPPFLAGS+= +#LDFLAGS=-static +LIBS= +vpath %.a + +SRC=pak.c pakfile.c + +%.d: %.c + $(MAKEDEPS) + +OBJ=$(patsubst %,%.o,$(basename $(SRC))) +DEP=$(patsubst %.o,%.d,$(OBJ)) + +all: $(EXE) + +$(EXE): $(OBJ) $(LIBS) + $(CC) $(LDFLAGS) -o $@ $^ -lQFutil -lz -lm + +clean: + rm -f $(EXE) *.o *.d core + +-include $(DEP) diff --git a/tools/pak/pak.c b/tools/pak/pak.c new file mode 100644 index 000000000..3fcbfae18 --- /dev/null +++ b/tools/pak/pak.c @@ -0,0 +1,14 @@ +#include "pakfile.h" + +int +main (int argc, char **argv) +{ + pack_t *pack; + int i; + + pack = pack_open (argv[1]); + for (i = 0; i < pack->numfiles; i++) + printf ("%6d %s\n", pack->files[i].filelen, pack->files[i].name); + pack_close (pack); + return 0; +} diff --git a/tools/pak/pakfile.c b/tools/pak/pakfile.c index c3703f079..8912c2005 100644 --- a/tools/pak/pakfile.c +++ b/tools/pak/pakfile.c @@ -3,60 +3,57 @@ #include #include -/* - Structs for pack files on disk -*/ +#include -#define PAK_PATH_LENGTH 56 +#include "pakfile.h" -typedef struct { - char name[PAK_PATH_LENGTH]; - int filepos, filelen; -} dpackfile_t; - -typedef struct { - char id[4]; - int dirofs; - int dirlen; -} dpackheader_t; - -#define MAX_FILES_IN_PACK 2048 - -typedef struct pack_s { - char filename[MAX_PATH]; - FILE *handle; - int numfiles; - int files_size; - dpackfile_t *files; -} pack_t; +static const char * +pack_get_key (void *p, void *unused) +{ + return ((dpackfile_t *) p)->name; +} pack_t * -new_pack (const char *name) +pack_new (const char *name) { pack_t *pack = calloc (sizeof (*pack), 1); if (!pack) return 0; - strncpy (pack->filename, name, sizeof (pack->filename)); - pack->filename[sizeof (pack->filename) - 1] = 0; + pack->filename = strdup (name); + if (!pack->filename) { + free (pack); + return 0; + } + pack->file_hash = Hash_NewTable (1021, pack_get_key, 0, 0); + if (!pack->file_hash) { + free (pack->filename); + free (pack); + return 0; + } return pack; } void -del_pack (pack_t *pack) +pack_del (pack_t *pack) { if (pack->files) free (pack->files); if (pack->handle) fclose (pack->handle); + if (pack->filename) + free (pack->filename); + if (pack->file_hash) + free (pack->file_hash); free (pack); } pack_t * -open_pack (const char *name) +pack_open (const char *name) { dpackheader_t header; - pack_t *pack = new_pack (name); + pack_t *pack = pack_new (name); + int i; if (!pack) return 0; @@ -64,7 +61,7 @@ open_pack (const char *name) if (!pack->handle) { goto error; } - if (fread (&header, sizeof (header), 1, pack->handle) != sizeof (header)) { + if (fread (&header, 1, sizeof (header), pack->handle) != sizeof (header)) { fprintf (stderr, "%s: not a pack file", name); goto error; } @@ -72,20 +69,37 @@ open_pack (const char *name) fprintf (stderr, "%s: not a pack file", name); goto error; } + + header.dirofs = LittleLong (header.dirofs); + header.dirlen = LittleLong (header.dirlen); + pack->numfiles = header.dirlen / sizeof (dpackfile_t); pack->files_size = pack->numfiles; if (pack->numfiles > MAX_FILES_IN_PACK) { fprintf (stderr, "%s: too many files in pack: %d", name, pack->numfiles); goto error; } - pack->files = malloc (numpackfiles * sizeof (packfile_t)); + pack->files = malloc (pack->files_size * sizeof (dpackfile_t)); if (!pack->files) { fprintf (stderr, "out of memory\n"); goto error; } - fseek (pack->handle, header.diroffs, SEEK_POS); + fseek (pack->handle, header.dirofs, SEEK_SET); fread (pack->files, pack->numfiles, sizeof (pack->files[0]), 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); + Hash_Add (pack->file_hash, &pack->files[i]); + } + return pack; error: - del_pack (pack); + pack_del (pack); return 0; } + +void +pack_close (pack_t *pack) +{ + pack_del (pack); +} diff --git a/tools/pak/pakfile.h b/tools/pak/pakfile.h new file mode 100644 index 000000000..4c5c924fd --- /dev/null +++ b/tools/pak/pakfile.h @@ -0,0 +1,21 @@ +#include + +#include +#include + +typedef struct pack_s { + char *filename; + FILE *handle; + int numfiles; + int files_size; + dpackfile_t *files; + hashtab_t *file_hash; +} 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);