can now dump a map's textures to a wad file (name currently based on bsp

file name (eg, foo.bsp -> foo.wad)
This commit is contained in:
Bill Currie 2004-01-15 07:16:44 +00:00
parent 7135ff9139
commit 31d970aca0
11 changed files with 205 additions and 62 deletions

View file

@ -32,27 +32,6 @@
#include "QF/wadfile.h"
//===============
// TYPES
//===============
#define CMP_NONE 0
#define CMP_LZSS 1
#define TYP_NONE 0
#define TYP_LABEL 1
#define TYP_LUMPY 64 // 64 + grab command number
#define TYP_PALETTE 64
#define TYP_QTEX 65
#define TYP_QPIC 66
#define TYP_SOUND 67
#define TYP_MIPTEX 68
typedef struct qpic_s {
int width, height;
byte data[4]; // variably sized
} qpic_t;
extern int wad_numlumps;
extern lumpinfo_t *wad_lumps;

View file

@ -33,6 +33,28 @@
#include "QF/quakeio.h"
#include "QF/qtypes.h"
//===============
// TYPES
//===============
#define CMP_NONE 0
#define CMP_LZSS 1
#define TYP_NONE 0
#define TYP_LABEL 1
#define TYP_LUMPY 64 // 64 + grab command number
#define TYP_PALETTE 64
#define TYP_QTEX 65
#define TYP_QPIC 66
#define TYP_SOUND 67
#define TYP_MIPTEX 68
typedef struct qpic_s {
int width, height;
byte data[4]; // variably sized
} qpic_t;
typedef struct wadinfo_s {
char id[4]; // should be WAD2 or 2DAW
int numlumps;
@ -72,6 +94,8 @@ void wad_close (wad_t *wad);
wad_t *wad_create (const char *name);
int wad_add (wad_t *wad, const char *filename, const char *lumpname,
byte type);
int wad_add_data (wad_t *wad, const char *lumpname, byte type,
const void *data, int bytes);
int wad_extract (wad_t *wad, lumpinfo_t *pf);
lumpinfo_t *wad_find_lump (wad_t *wad, const char *filename);

View file

@ -186,8 +186,7 @@ pack_close (pack_t *pack)
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]));
pack->header.dirlen = LittleLong (pack->header.dirlen);
Qseek (pack->handle, 0, SEEK_SET);
Qwrite (pack->handle, &pack->header, sizeof (pack->header));

View file

@ -176,7 +176,7 @@ wad_create (const char *name)
wad_del (wad);
return 0;
}
strncpy (wad->header.id, "PACK", sizeof (wad->header.id));
strncpy (wad->header.id, "WAD2", sizeof (wad->header.id));
Qwrite (wad->handle, &wad->header, sizeof (wad->header));
@ -200,10 +200,8 @@ wad_close (wad_t *wad)
Qseek (wad->handle, wad->header.infotableofs, SEEK_SET);
Qwrite (wad->handle, wad->lumps,
wad->numlumps * sizeof (wad->lumps[0]));
wad->header.numlumps = wad->numlumps * sizeof (wad->lumps[0]);
wad->header.infotableofs = LittleLong (wad->header.infotableofs);
wad->header.numlumps = LittleLong (wad->numlumps
* sizeof (wad->lumps[0]));
wad->header.numlumps = LittleLong (wad->numlumps);
Qseek (wad->handle, 0, SEEK_SET);
Qwrite (wad->handle, &wad->header, sizeof (wad->header));
@ -251,6 +249,7 @@ wad_add (wad_t *wad, const char *filename, const char *lumpname, byte type)
Qseek (wad->handle, 0, SEEK_END);
pf->filepos = Qtell (wad->handle);
pf->type = type;
pf->size = 0;
while ((bytes = Qread (file, buffer, sizeof (buffer)))) {
Qwrite (wad->handle, buffer, bytes);
@ -265,6 +264,52 @@ wad_add (wad_t *wad, const char *filename, const char *lumpname, byte type)
return 0;
}
int
wad_add_data (wad_t *wad, const char *lumpname, byte type, const void *data,
int bytes)
{
lumpinfo_t *pf;
lumpinfo_t dummy;
strncpy (dummy.name, lumpname, 16);
dummy.name[15] = 0;
pf = Hash_FindElement (wad->lump_hash, &dummy);
if (pf)
return -1;
if (wad->numlumps == wad->lumps_size) {
lumpinfo_t *f;
wad->lumps_size += 64;
f = realloc (wad->lumps, wad->lumps_size * sizeof (lumpinfo_t));
if (!f)
return -1;
wad->lumps = f;
}
wad->modified = 1;
pf = &wad->lumps[wad->numlumps++];
strncpy (pf->name, lumpname, sizeof (pf->name));
pf->name[sizeof (pf->name) - 1] = 0;
Qseek (wad->handle, 0, SEEK_END);
pf->filepos = Qtell (wad->handle);
pf->type = type;
pf->size = bytes;
Qwrite (wad->handle, data, bytes);
if (wad->pad && pf->size & 3) {
static char buf[4];
Qwrite (wad->handle, buf, 4 - (pf->size & 3));
}
Hash_AddElement (wad->lump_hash, pf);
return 0;
}
static int
make_parents (const char *_path)
{

View file

@ -246,6 +246,7 @@ qboolean FillOutside (node_t *node);
void LoadBSP (void);
void bsp2prt (void);
void extract_textures (void);
//=============================================================================

View file

@ -39,6 +39,7 @@ typedef struct {
qboolean noclip;
qboolean onlyents;
qboolean portal;
qboolean extract_textures;
qboolean usehulls;
qboolean watervis;
int hullnum;

View file

@ -48,21 +48,22 @@ static __attribute__ ((unused)) const char rcsid[] =
const char *this_program;
static struct option const long_options[] = {
{"quiet", no_argument, 0, 'q'},
{"verbose", no_argument, 0, 'v'},
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'},
{"draw", no_argument, 0, 'd'},
{"notjunc", no_argument, 0, 't'},
{"nofill", no_argument, 0, 'f'},
{"noclip", no_argument, 0, 'c'},
{"onlyents", no_argument, 0, 'e'},
{"portal", no_argument, 0, 'p'},
{"usehulls", no_argument, 0, 'u'},
{"hullnum", required_argument, 0, 'H'},
{"subdivide", required_argument, 0, 's'},
{"wadpath", required_argument, 0, 'w'},
{"watervis", no_argument, 0, 'W'},
{"quiet", no_argument, 0, 'q'},
{"verbose", no_argument, 0, 'v'},
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'},
{"draw", no_argument, 0, 'd'},
{"notjunc", no_argument, 0, 't'},
{"nofill", no_argument, 0, 'f'},
{"noclip", no_argument, 0, 'c'},
{"onlyents", no_argument, 0, 'e'},
{"portal", no_argument, 0, 'p'},
{"extract-textures", no_argument, 0, 'E'},
{"usehulls", no_argument, 0, 'u'},
{"hullnum", required_argument, 0, 'H'},
{"subdivide", required_argument, 0, 's'},
{"wadpath", required_argument, 0, 'w'},
{"watervis", no_argument, 0, 'W'},
{NULL, 0, NULL, 0}
};
@ -77,6 +78,7 @@ static const char *short_options =
"c" // noclip
"e" // onlyents
"p" // portal
"E" // extract-texures
"u" // usehulls
"H:" // hullnum
"s:" // subdivide
@ -101,6 +103,7 @@ usage (int status)
" -c, --noclip\n"
" -e, --onlyents\n"
" -p, --portal\n"
" -E, --extract-textures\n"
" -u, --usehulls Use the existing hull files\n"
" -H, --hullnum [num]\n"
" -s, --subdivide [size]\n"
@ -154,6 +157,9 @@ DecodeArgs (int argc, char **argv)
case 'p': // portal
options.portal = true;
break;
case 'E': // extract-textures
options.extract_textures = true;
break;
case 'u': // usehulls
options.usehulls = true;
break;

View file

@ -771,6 +771,12 @@ ProcessFile (void)
return;
}
if (options.extract_textures) {
LoadBSP ();
extract_textures ();
return;
}
// load brushes and entities
LoadMapFile (options.mapfile);

View file

@ -46,6 +46,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/dstring.h"
#include "QF/qendian.h"
#include "QF/quakefs.h"
#include "QF/sys.h"
#include "QF/va.h"
#include "QF/wad.h"
@ -251,3 +252,102 @@ bsp2prt (void)
PortalizeWorld (nodes);
WritePortalfile (nodes);
}
static byte default_palette[] = {
0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x1F, 0x1F, 0x1F, 0x2F, 0x2F, 0x2F,
0x3F, 0x3F, 0x3F, 0x4B, 0x4B, 0x4B, 0x5B, 0x5B, 0x5B, 0x6B, 0x6B, 0x6B,
0x7B, 0x7B, 0x7B, 0x8B, 0x8B, 0x8B, 0x9B, 0x9B, 0x9B, 0xAB, 0xAB, 0xAB,
0xBB, 0xBB, 0xBB, 0xCB, 0xCB, 0xCB, 0xDB, 0xDB, 0xDB, 0xEB, 0xEB, 0xEB,
0x0F, 0x0B, 0x07, 0x17, 0x0F, 0x0B, 0x1F, 0x17, 0x0B, 0x27, 0x1B, 0x0F,
0x2F, 0x23, 0x13, 0x37, 0x2B, 0x17, 0x3F, 0x2F, 0x17, 0x4B, 0x37, 0x1B,
0x53, 0x3B, 0x1B, 0x5B, 0x43, 0x1F, 0x63, 0x4B, 0x1F, 0x6B, 0x53, 0x1F,
0x73, 0x57, 0x1F, 0x7B, 0x5F, 0x23, 0x83, 0x67, 0x23, 0x8F, 0x6F, 0x23,
0x0B, 0x0B, 0x0F, 0x13, 0x13, 0x1B, 0x1B, 0x1B, 0x27, 0x27, 0x27, 0x33,
0x2F, 0x2F, 0x3F, 0x37, 0x37, 0x4B, 0x3F, 0x3F, 0x57, 0x47, 0x47, 0x67,
0x4F, 0x4F, 0x73, 0x5B, 0x5B, 0x7F, 0x63, 0x63, 0x8B, 0x6B, 0x6B, 0x97,
0x73, 0x73, 0xA3, 0x7B, 0x7B, 0xAF, 0x83, 0x83, 0xBB, 0x8B, 0x8B, 0xCB,
0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x0B, 0x0B, 0x00, 0x13, 0x13, 0x00,
0x1B, 0x1B, 0x00, 0x23, 0x23, 0x00, 0x2B, 0x2B, 0x07, 0x2F, 0x2F, 0x07,
0x37, 0x37, 0x07, 0x3F, 0x3F, 0x07, 0x47, 0x47, 0x07, 0x4B, 0x4B, 0x0B,
0x53, 0x53, 0x0B, 0x5B, 0x5B, 0x0B, 0x63, 0x63, 0x0B, 0x6B, 0x6B, 0x0F,
0x07, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x17, 0x00, 0x00, 0x1F, 0x00, 0x00,
0x27, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x37, 0x00, 0x00, 0x3F, 0x00, 0x00,
0x47, 0x00, 0x00, 0x4F, 0x00, 0x00, 0x57, 0x00, 0x00, 0x5F, 0x00, 0x00,
0x67, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x77, 0x00, 0x00, 0x7F, 0x00, 0x00,
0x13, 0x13, 0x00, 0x1B, 0x1B, 0x00, 0x23, 0x23, 0x00, 0x2F, 0x2B, 0x00,
0x37, 0x2F, 0x00, 0x43, 0x37, 0x00, 0x4B, 0x3B, 0x07, 0x57, 0x43, 0x07,
0x5F, 0x47, 0x07, 0x6B, 0x4B, 0x0B, 0x77, 0x53, 0x0F, 0x83, 0x57, 0x13,
0x8B, 0x5B, 0x13, 0x97, 0x5F, 0x1B, 0xA3, 0x63, 0x1F, 0xAF, 0x67, 0x23,
0x23, 0x13, 0x07, 0x2F, 0x17, 0x0B, 0x3B, 0x1F, 0x0F, 0x4B, 0x23, 0x13,
0x57, 0x2B, 0x17, 0x63, 0x2F, 0x1F, 0x73, 0x37, 0x23, 0x7F, 0x3B, 0x2B,
0x8F, 0x43, 0x33, 0x9F, 0x4F, 0x33, 0xAF, 0x63, 0x2F, 0xBF, 0x77, 0x2F,
0xCF, 0x8F, 0x2B, 0xDF, 0xAB, 0x27, 0xEF, 0xCB, 0x1F, 0xFF, 0xF3, 0x1B,
0x0B, 0x07, 0x00, 0x1B, 0x13, 0x00, 0x2B, 0x23, 0x0F, 0x37, 0x2B, 0x13,
0x47, 0x33, 0x1B, 0x53, 0x37, 0x23, 0x63, 0x3F, 0x2B, 0x6F, 0x47, 0x33,
0x7F, 0x53, 0x3F, 0x8B, 0x5F, 0x47, 0x9B, 0x6B, 0x53, 0xA7, 0x7B, 0x5F,
0xB7, 0x87, 0x6B, 0xC3, 0x93, 0x7B, 0xD3, 0xA3, 0x8B, 0xE3, 0xB3, 0x97,
0xAB, 0x8B, 0xA3, 0x9F, 0x7F, 0x97, 0x93, 0x73, 0x87, 0x8B, 0x67, 0x7B,
0x7F, 0x5B, 0x6F, 0x77, 0x53, 0x63, 0x6B, 0x4B, 0x57, 0x5F, 0x3F, 0x4B,
0x57, 0x37, 0x43, 0x4B, 0x2F, 0x37, 0x43, 0x27, 0x2F, 0x37, 0x1F, 0x23,
0x2B, 0x17, 0x1B, 0x23, 0x13, 0x13, 0x17, 0x0B, 0x0B, 0x0F, 0x07, 0x07,
0xBB, 0x73, 0x9F, 0xAF, 0x6B, 0x8F, 0xA3, 0x5F, 0x83, 0x97, 0x57, 0x77,
0x8B, 0x4F, 0x6B, 0x7F, 0x4B, 0x5F, 0x73, 0x43, 0x53, 0x6B, 0x3B, 0x4B,
0x5F, 0x33, 0x3F, 0x53, 0x2B, 0x37, 0x47, 0x23, 0x2B, 0x3B, 0x1F, 0x23,
0x2F, 0x17, 0x1B, 0x23, 0x13, 0x13, 0x17, 0x0B, 0x0B, 0x0F, 0x07, 0x07,
0xDB, 0xC3, 0xBB, 0xCB, 0xB3, 0xA7, 0xBF, 0xA3, 0x9B, 0xAF, 0x97, 0x8B,
0xA3, 0x87, 0x7B, 0x97, 0x7B, 0x6F, 0x87, 0x6F, 0x5F, 0x7B, 0x63, 0x53,
0x6B, 0x57, 0x47, 0x5F, 0x4B, 0x3B, 0x53, 0x3F, 0x33, 0x43, 0x33, 0x27,
0x37, 0x2B, 0x1F, 0x27, 0x1F, 0x17, 0x1B, 0x13, 0x0F, 0x0F, 0x0B, 0x07,
0x6F, 0x83, 0x7B, 0x67, 0x7B, 0x6F, 0x5F, 0x73, 0x67, 0x57, 0x6B, 0x5F,
0x4F, 0x63, 0x57, 0x47, 0x5B, 0x4F, 0x3F, 0x53, 0x47, 0x37, 0x4B, 0x3F,
0x2F, 0x43, 0x37, 0x2B, 0x3B, 0x2F, 0x23, 0x33, 0x27, 0x1F, 0x2B, 0x1F,
0x17, 0x23, 0x17, 0x0F, 0x1B, 0x13, 0x0B, 0x13, 0x0B, 0x07, 0x0B, 0x07,
0xFF, 0xF3, 0x1B, 0xEF, 0xDF, 0x17, 0xDB, 0xCB, 0x13, 0xCB, 0xB7, 0x0F,
0xBB, 0xA7, 0x0F, 0xAB, 0x97, 0x0B, 0x9B, 0x83, 0x07, 0x8B, 0x73, 0x07,
0x7B, 0x63, 0x07, 0x6B, 0x53, 0x00, 0x5B, 0x47, 0x00, 0x4B, 0x37, 0x00,
0x3B, 0x2B, 0x00, 0x2B, 0x1F, 0x00, 0x1B, 0x0F, 0x00, 0x0B, 0x07, 0x00,
0x00, 0x00, 0xFF, 0x0B, 0x0B, 0xEF, 0x13, 0x13, 0xDF, 0x1B, 0x1B, 0xCF,
0x23, 0x23, 0xBF, 0x2B, 0x2B, 0xAF, 0x2F, 0x2F, 0x9F, 0x2F, 0x2F, 0x8F,
0x2F, 0x2F, 0x7F, 0x2F, 0x2F, 0x6F, 0x2F, 0x2F, 0x5F, 0x2B, 0x2B, 0x4F,
0x23, 0x23, 0x3F, 0x1B, 0x1B, 0x2F, 0x13, 0x13, 0x1F, 0x0B, 0x0B, 0x0F,
0x2B, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x4B, 0x07, 0x00, 0x5F, 0x07, 0x00,
0x6F, 0x0F, 0x00, 0x7F, 0x17, 0x07, 0x93, 0x1F, 0x07, 0xA3, 0x27, 0x0B,
0xB7, 0x33, 0x0F, 0xC3, 0x4B, 0x1B, 0xCF, 0x63, 0x2B, 0xDB, 0x7F, 0x3B,
0xE3, 0x97, 0x4F, 0xE7, 0xAB, 0x5F, 0xEF, 0xBF, 0x77, 0xF7, 0xD3, 0x8B,
0xA7, 0x7B, 0x3B, 0xB7, 0x9B, 0x37, 0xC7, 0xC3, 0x37, 0xE7, 0xE3, 0x57,
0x7F, 0xBF, 0xFF, 0xAB, 0xE7, 0xFF, 0xD7, 0xFF, 0xFF, 0x67, 0x00, 0x00,
0x8B, 0x00, 0x00, 0xB3, 0x00, 0x00, 0xD7, 0x00, 0x00, 0xFF, 0x00, 0x00,
0xFF, 0xF3, 0x93, 0xFF, 0xF7, 0xC7, 0xFF, 0xFF, 0xFF, 0x9F, 0x5B, 0x53,
};
void
extract_textures (void)
{
dmiptexlump_t *miptexlump = (dmiptexlump_t *) bsp->texdata;
miptex_t *miptex;
int i, mtsize, pixels;
char *wadfile = malloc (strlen (options.bspfile) + 5);
wad_t *wad;
wadfile = malloc (strlen (options.bspfile) + 5);
QFS_StripExtension (options.bspfile, wadfile);
strcat (wadfile, ".wad");
wad = wad_create (wadfile);
wad_add_data (wad, "PALETTE", TYP_PALETTE, default_palette,
sizeof (default_palette));
for (i = 0; i < miptexlump->nummiptex; i++) {
printf ("%3d %6d ", i, miptexlump->dataofs[i]);
miptex = (miptex_t *)(bsp->texdata + miptexlump->dataofs[i]);
pixels = miptex->width * miptex->height / 64 * 85;
mtsize = sizeof (miptex_t) + pixels;
printf ("%16s %3dx%-3d %d %d %d %d %d %d\n",
miptex->name, miptex->width,
miptex->height, miptex->offsets[0], miptex->offsets[1],
miptex->offsets[2], miptex->offsets[3], pixels, mtsize);
wad_add_data (wad, miptex->name, TYP_MIPTEX, miptex, mtsize);
}
wad_close (wad);
}

View file

@ -285,22 +285,6 @@ typedef struct wadlist_s {
wadlist_t *wadlist;
static void
CleanupName (char *in, char *out)
{
int i;
for (i = 0; i < 16; i++) {
if (!in[i])
break;
out[i] = toupper (in[i]);
}
for (; i < 16; i++)
out[i] = 0;
}
static int
TEX_InitFromWad (char *path)
{
@ -329,15 +313,12 @@ TEX_InitFromWad (char *path)
static int
LoadLump (char *name, dstring_t *dest)
{
char cname[16]; //FIXME: overflow
int r;
int ofs = dest->size;
wadlist_t *wl;
lumpinfo_t *lump;
QFile *texfile;
CleanupName (name, cname);
for (wl = wadlist; wl; wl = wl->next) {
if ((lump = wad_find_lump (wl->wad, name))) {
dest->size += lump->disksize;

View file

@ -206,7 +206,8 @@ main (int argc, char **argv)
if (options.verbosity >= 1)
printf ("%6d ", wad->lumps[i].size);
if (options.verbosity >= 0)
printf ("%s\n", wad->lumps[i].name);
printf ("%3d %s\n", wad->lumps[i].type,
wad->lumps[i].name);
}
wad_close (wad);
break;