qbsp: make wadlist a null-terminated linked list of wads
Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
This commit is contained in:
parent
0348f64274
commit
a9e05ffd07
17
qbsp/qbsp.c
17
qbsp/qbsp.c
|
|
@ -290,8 +290,7 @@ ProcessFile(void)
|
||||||
{
|
{
|
||||||
const char *wadstring;
|
const char *wadstring;
|
||||||
char *defaultwad;
|
char *defaultwad;
|
||||||
wad_t *wads;
|
wad_t *wadlist;
|
||||||
int numwads = 0;
|
|
||||||
|
|
||||||
// load brushes and entities
|
// load brushes and entities
|
||||||
LoadMapFile();
|
LoadMapFile();
|
||||||
|
|
@ -300,15 +299,16 @@ ProcessFile(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wadlist = NULL;
|
||||||
wadstring = ValueForKey(pWorldEnt, "_wad");
|
wadstring = ValueForKey(pWorldEnt, "_wad");
|
||||||
if (!wadstring[0])
|
if (!wadstring[0])
|
||||||
wadstring = ValueForKey(pWorldEnt, "wad");
|
wadstring = ValueForKey(pWorldEnt, "wad");
|
||||||
if (!wadstring[0])
|
if (!wadstring[0])
|
||||||
Message(msgWarning, warnNoWadKey);
|
Message(msgWarning, warnNoWadKey);
|
||||||
else
|
else
|
||||||
numwads = WADList_Init(&wads, wadstring);
|
wadlist = WADList_Init(wadstring);
|
||||||
|
|
||||||
if (!numwads) {
|
if (!wadlist) {
|
||||||
if (wadstring[0])
|
if (wadstring[0])
|
||||||
Message(msgWarning, warnNoValidWads);
|
Message(msgWarning, warnNoValidWads);
|
||||||
/* Try the default wad name */
|
/* Try the default wad name */
|
||||||
|
|
@ -316,8 +316,8 @@ ProcessFile(void)
|
||||||
strcpy(defaultwad, options.szMapName);
|
strcpy(defaultwad, options.szMapName);
|
||||||
StripExtension(defaultwad);
|
StripExtension(defaultwad);
|
||||||
DefaultExtension(defaultwad, ".wad");
|
DefaultExtension(defaultwad, ".wad");
|
||||||
numwads = WADList_Init(&wads, defaultwad);
|
wadlist = WADList_Init(defaultwad);
|
||||||
if (numwads)
|
if (wadlist)
|
||||||
Message(msgLiteral, "Using default WAD: %s\n", defaultwad);
|
Message(msgLiteral, "Using default WAD: %s\n", defaultwad);
|
||||||
FreeMem(defaultwad, OTHER, strlen(options.szMapName) + 5);
|
FreeMem(defaultwad, OTHER, strlen(options.szMapName) + 5);
|
||||||
}
|
}
|
||||||
|
|
@ -325,16 +325,15 @@ ProcessFile(void)
|
||||||
// init the tables to be shared by all models
|
// init the tables to be shared by all models
|
||||||
BeginBSPFile();
|
BeginBSPFile();
|
||||||
|
|
||||||
// the clipping hulls will not be written out to text files by forked processes :)
|
|
||||||
if (!options.fAllverbose)
|
if (!options.fAllverbose)
|
||||||
options.fVerbose = false;
|
options.fVerbose = false;
|
||||||
CreateHulls();
|
CreateHulls();
|
||||||
|
|
||||||
WriteEntitiesToString();
|
WriteEntitiesToString();
|
||||||
WADList_Process(wads, numwads);
|
WADList_Process(wadlist);
|
||||||
FinishBSPFile();
|
FinishBSPFile();
|
||||||
|
|
||||||
WADList_Free(wads, numwads);
|
WADList_Free(wadlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
168
qbsp/wad.c
168
qbsp/wad.c
|
|
@ -24,9 +24,9 @@
|
||||||
#include "qbsp.h"
|
#include "qbsp.h"
|
||||||
#include "wad.h"
|
#include "wad.h"
|
||||||
|
|
||||||
static void WADList_LoadTextures(wad_t *wads, int numwads, dmiptexlump_t *l);
|
static void WADList_LoadTextures(const wad_t *wadlist, dmiptexlump_t *lump);
|
||||||
static void WADList_AddAnimatingTextures(wad_t *wads, int numwads);
|
static void WADList_AddAnimatingTextures(const wad_t *wadlist);
|
||||||
static int WAD_LoadLump(wad_t *w, char *name, byte *dest);
|
static int WAD_LoadLump(const wad_t *wad, const char *name, byte *dest);
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
@ -76,34 +76,21 @@ WAD_LoadInfo(wad_t *wad)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
wad_t *
|
||||||
WADList_Init(wad_t **wads, const char *wadstring)
|
WADList_Init(const char *wadstring)
|
||||||
{
|
{
|
||||||
int len, numwads;
|
int len;
|
||||||
wad_t *wadlist, *wad;
|
wad_t wad, *wadlist, *newwad;
|
||||||
const char *fname;
|
const char *fname;
|
||||||
char *fpath;
|
char *fpath;
|
||||||
const char *pos;
|
const char *pos;
|
||||||
int pathlen;
|
int pathlen;
|
||||||
|
|
||||||
*wads = NULL;
|
if (!wadstring || !wadstring[0])
|
||||||
|
return NULL;
|
||||||
if (!wadstring)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
wadlist = NULL;
|
||||||
len = strlen(wadstring);
|
len = strlen(wadstring);
|
||||||
if (len == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Count # of wads
|
|
||||||
numwads = 1;
|
|
||||||
for (pos = wadstring; *pos ; pos++)
|
|
||||||
if (pos[0] == ';' && pos[1] != ';')
|
|
||||||
numwads++;
|
|
||||||
|
|
||||||
wadlist = AllocMem(OTHER, numwads * sizeof(wad_t), true);
|
|
||||||
|
|
||||||
wad = wadlist;
|
|
||||||
pos = wadstring;
|
pos = wadstring;
|
||||||
while (pos - wadstring < len) {
|
while (pos - wadstring < len) {
|
||||||
fname = pos;
|
fname = pos;
|
||||||
|
|
@ -118,76 +105,68 @@ WADList_Init(wad_t **wads, const char *wadstring)
|
||||||
fpath = AllocMem(OTHER, pathlen + 1, true);
|
fpath = AllocMem(OTHER, pathlen + 1, true);
|
||||||
snprintf(fpath, pathlen + 1, "%s/%s", options.wadPath, fname);
|
snprintf(fpath, pathlen + 1, "%s/%s", options.wadPath, fname);
|
||||||
}
|
}
|
||||||
wad->file = fopen(fpath, "rb");
|
wad.file = fopen(fpath, "rb");
|
||||||
if (wad->file) {
|
if (wad.file) {
|
||||||
if (options.fVerbose)
|
if (options.fVerbose)
|
||||||
Message(msgLiteral, "Opened WAD: %s\n", fpath);
|
Message(msgLiteral, "Opened WAD: %s\n", fpath);
|
||||||
if (WAD_LoadInfo(wad)) {
|
if (WAD_LoadInfo(&wad)) {
|
||||||
wad++;
|
newwad = AllocMem(OTHER, sizeof(wad), true);
|
||||||
|
memcpy(newwad, &wad, sizeof(wad));
|
||||||
|
newwad->next = wadlist;
|
||||||
|
wadlist = newwad;
|
||||||
} else {
|
} else {
|
||||||
Message(msgWarning, warnNotWad, fpath);
|
Message(msgWarning, warnNotWad, fpath);
|
||||||
fclose(wad->file);
|
fclose(wad.file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FreeMem(fpath, OTHER, strlen(fpath) + 1);
|
FreeMem(fpath, OTHER, strlen(fpath) + 1);
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Re-allocate just the required amount */
|
return wadlist;
|
||||||
*wads = AllocMem(OTHER, (wad - wadlist) * sizeof(wad_t), false);
|
|
||||||
memcpy(*wads, wadlist, (wad - wadlist) * sizeof(wad_t));
|
|
||||||
FreeMem(wadlist, OTHER, numwads * sizeof(wad_t));
|
|
||||||
numwads = wad - wadlist;
|
|
||||||
|
|
||||||
return numwads;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
WADList_Free(wad_t *wads, int numwads)
|
WADList_Free(wad_t *wadlist)
|
||||||
{
|
{
|
||||||
int i;
|
wad_t *wad, *next;
|
||||||
|
|
||||||
if (wads) {
|
for (wad = wadlist; wad; wad = next) {
|
||||||
for (i = 0; i < numwads; i++) {
|
next = wad->next;
|
||||||
fclose(wads[i].file);
|
fclose(wad->file);
|
||||||
FreeMem(wads[i].lumps, OTHER,
|
FreeMem(wad->lumps, OTHER, sizeof(lumpinfo_t) * wad->header.numlumps);
|
||||||
sizeof(lumpinfo_t) * wads[i].header.numlumps);
|
FreeMem(wad, OTHER, sizeof(*wad));
|
||||||
}
|
|
||||||
FreeMem(wads, OTHER, numwads * sizeof(wad_t));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static lumpinfo_t *
|
static lumpinfo_t *
|
||||||
WADList_FindTexture(const wad_t *wads, int numwads, const char *name)
|
WADList_FindTexture(const wad_t *wadlist, const char *name)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i;
|
||||||
const wad_t *wad;
|
const wad_t *wad;
|
||||||
|
|
||||||
for (i = 0, wad = wads; i < numwads; i++, wad++)
|
for (wad = wadlist; wad; wad = wad->next)
|
||||||
for (j = 0; j < wad->header.numlumps; j++)
|
for (i = 0; i < wad->header.numlumps; i++)
|
||||||
if (!strcasecmp(name, wad->lumps[j].name))
|
if (!strcasecmp(name, wad->lumps[i].name))
|
||||||
return &wad->lumps[j];
|
return &wad->lumps[i];
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WADList_Process(wad_t *wads, int numwads)
|
WADList_Process(const wad_t *wadlist)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
lumpinfo_t *texture;
|
lumpinfo_t *texture;
|
||||||
dmiptexlump_t *miptexlump;
|
dmiptexlump_t *miptexlump;
|
||||||
struct lumpdata *texdata = &pWorldEnt->lumps[BSPTEX];
|
struct lumpdata *texdata = &pWorldEnt->lumps[BSPTEX];
|
||||||
|
|
||||||
if (numwads < 1)
|
WADList_AddAnimatingTextures(wadlist);
|
||||||
return;
|
|
||||||
|
|
||||||
WADList_AddAnimatingTextures(wads, numwads);
|
|
||||||
|
|
||||||
// Count texture size. Slow but saves memory.
|
// Count texture size. Slow but saves memory.
|
||||||
for (i = 0; i < map.nummiptex; i++) {
|
for (i = 0; i < map.nummiptex; i++) {
|
||||||
texture = WADList_FindTexture(wads, numwads, map.miptex[i]);
|
texture = WADList_FindTexture(wadlist, map.miptex[i]);
|
||||||
if (texture)
|
if (texture)
|
||||||
texdata->count += texture->disksize;
|
texdata->count += texture->disksize;
|
||||||
}
|
}
|
||||||
|
|
@ -198,58 +177,57 @@ WADList_Process(wad_t *wads, int numwads)
|
||||||
miptexlump = (dmiptexlump_t *)texdata->data;
|
miptexlump = (dmiptexlump_t *)texdata->data;
|
||||||
miptexlump->nummiptex = map.nummiptex;
|
miptexlump->nummiptex = map.nummiptex;
|
||||||
|
|
||||||
WADList_LoadTextures(wads, numwads, miptexlump);
|
WADList_LoadTextures(wadlist, miptexlump);
|
||||||
|
|
||||||
// Last pass, mark unfound textures as such
|
// Last pass, mark unfound textures as such
|
||||||
for (i = 0; i < map.nummiptex; i++)
|
for (i = 0; i < map.nummiptex; i++) {
|
||||||
if (miptexlump->dataofs[i] == 0) {
|
if (miptexlump->dataofs[i] == 0) {
|
||||||
miptexlump->dataofs[i] = -1;
|
miptexlump->dataofs[i] = -1;
|
||||||
Message(msgWarning, warnTextureNotFound, map.miptex[i]);
|
Message(msgWarning, warnTextureNotFound, map.miptex[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
WADList_LoadTextures(wad_t *wads, int numwads, dmiptexlump_t *l)
|
static void
|
||||||
{
|
WADList_LoadTextures(const wad_t *wadlist, dmiptexlump_t *lump)
|
||||||
int i, j, len;
|
{
|
||||||
byte *data;
|
int i, size;
|
||||||
struct lumpdata *texdata = &pWorldEnt->lumps[BSPTEX];
|
byte *data;
|
||||||
|
const wad_t *wad;
|
||||||
data = (byte *)&l->dataofs[map.nummiptex];
|
struct lumpdata *texdata = &pWorldEnt->lumps[BSPTEX];
|
||||||
for (i = 0; i < numwads; i++) {
|
|
||||||
for (j = 0; j < map.nummiptex; j++) {
|
data = (byte *)&lump->dataofs[map.nummiptex];
|
||||||
// Texture already found in a previous WAD
|
|
||||||
if (l->dataofs[j] != 0)
|
for (i = 0; i < map.nummiptex; i++) {
|
||||||
continue;
|
if (lump->dataofs[i])
|
||||||
|
continue;
|
||||||
l->dataofs[j] = data - (byte *)l;
|
for (wad = wadlist; wad; wad = wad->next) {
|
||||||
len = WAD_LoadLump(wads + i, map.miptex[j], data);
|
size = WAD_LoadLump(wad, map.miptex[i], data);
|
||||||
if (data + len - (byte *)texdata->data > texdata->count)
|
if (size)
|
||||||
Error(errLowTextureCount);
|
break;
|
||||||
|
}
|
||||||
// didn't find the texture
|
if (data + size - (byte *)texdata->data > texdata->count)
|
||||||
if (!len)
|
Error(errLowTextureCount);
|
||||||
l->dataofs[j] = 0;
|
lump->dataofs[i] = data - (byte *)lump;
|
||||||
data += len;
|
data += size;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
WAD_LoadLump(wad_t *w, char *name, byte *dest)
|
WAD_LoadLump(const wad_t *wad, const char *name, byte *dest)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int len;
|
int size;
|
||||||
|
|
||||||
for (i = 0; i < w->header.numlumps; i++) {
|
for (i = 0; i < wad->header.numlumps; i++) {
|
||||||
if (!strcasecmp(name, w->lumps[i].name)) {
|
if (!strcasecmp(name, wad->lumps[i].name)) {
|
||||||
fseek(w->file, w->lumps[i].filepos, SEEK_SET);
|
fseek(wad->file, wad->lumps[i].filepos, SEEK_SET);
|
||||||
len = fread(dest, 1, w->lumps[i].disksize, w->file);
|
size = fread(dest, 1, wad->lumps[i].disksize, wad->file);
|
||||||
if (len != w->lumps[i].disksize)
|
if (size != wad->lumps[i].disksize)
|
||||||
Error(errReadFailure);
|
Error(errReadFailure);
|
||||||
return w->lumps[i].disksize;
|
return wad->lumps[i].disksize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -258,7 +236,7 @@ WAD_LoadLump(wad_t *w, char *name, byte *dest)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
WADList_AddAnimatingTextures(wad_t *wads, int numwads)
|
WADList_AddAnimatingTextures(const wad_t *wadlist)
|
||||||
{
|
{
|
||||||
int base;
|
int base;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
@ -274,7 +252,7 @@ WADList_AddAnimatingTextures(wad_t *wads, int numwads)
|
||||||
/* Search for all animations (0-9) and alt-animations (A-J) */
|
/* Search for all animations (0-9) and alt-animations (A-J) */
|
||||||
for (j = 0; j < 20; j++) {
|
for (j = 0; j < 20; j++) {
|
||||||
name[1] = (j < 10) ? '0' + j : 'A' + j - 10;
|
name[1] = (j < 10) ? '0' + j : 'A' + j - 10;
|
||||||
if (WADList_FindTexture(wads, numwads, name))
|
if (WADList_FindTexture(wadlist, name))
|
||||||
FindMiptex(name);
|
FindMiptex(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,15 +47,16 @@ typedef struct {
|
||||||
uint32_t offsets[MIPLEVELS];
|
uint32_t offsets[MIPLEVELS];
|
||||||
} dmiptex_t;
|
} dmiptex_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct wad_s {
|
||||||
wadinfo_t header;
|
wadinfo_t header;
|
||||||
int version;
|
int version;
|
||||||
lumpinfo_t *lumps;
|
lumpinfo_t *lumps;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
struct wad_s *next;
|
||||||
} wad_t;
|
} wad_t;
|
||||||
|
|
||||||
int WADList_Init(wad_t **wads, const char *wadstring);
|
wad_t *WADList_Init(const char *wadstring);
|
||||||
void WADList_Process(wad_t *wads, int numwads);
|
void WADList_Process(const wad_t *wadlist);
|
||||||
void WADList_Free(wad_t *wads, int numwads);
|
void WADList_Free(wad_t *wadlist);
|
||||||
|
|
||||||
#endif /* WAD_H */
|
#endif /* WAD_H */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue