commit a28f2f4333102961668354d75850c7ffebbdb194
Author: Simon Howard <fraggle@soulsphere.org>
AuthorDate: Sun Aug 16 19:55:47 2015 -0400
Commit: Simon Howard <fraggle@soulsphere.org>
CommitDate: Sun Aug 16 20:04:29 2015 -0400
wad: Change type of lumpinfo[] array.
Originally lumpinfo[] was an array of lumpinfo_t structs. However,
this is problematic because the array must be realloc()ed to
increase its size with each load of a new WAD. If data from one of
the WADs has already been cached in memory, the zone memory system's
user pointer can end up pointing at freed memory.
Therefore, any modification to lumpinfo[] had to be carefully
controlled - see previous commit d5b6bb70919f that applied an
attempted fix. However, this fix did not fix loading using the
merging command line parameters, which change lumpinfo[] in far more
complicated ways.
Instead, this fixes the issue in a more fundamental way. lumpinfo[]
is now an array of pointers to lumpinfo_t structs, disconnecting
their memory locations from their location in the lumpinfo[] array.
It's now possible to change or rearrange the array in any desired
way without the zone user pointers getting out of sync.
This also includes a minor change to define a lumpindex_t type for
representing lumpinfo[] indices, to make the WAD API more literate.
Thanks to Fabian Greffrath for identifying that the bug was still
present when using the merge parameters. This fixes #442 (again).
---
src/deh_io.c | 2 +-
src/doom/d_main.c | 8 +-
src/doom/r_data.c | 6 +-
src/doom/r_things.c | 14 ++--
src/heretic/d_main.c | 2 +-
src/heretic/r_data.c | 6 +-
src/heretic/r_things.c | 12 +--
src/hexen/h2_main.c | 2 +-
src/hexen/r_data.c | 6 +-
src/hexen/r_things.c | 12 +--
src/i_sdlmusic.c | 2 +-
src/strife/d_main.c | 2 +-
src/strife/r_data.c | 6 +-
src/strife/r_things.c | 14 ++--
src/w_checksum.c | 8 +-
src/w_merge.c | 65 ++++++++---------
src/w_wad.c | 195 +++++++++++++++++++++----------------------------
src/w_wad.h | 28 +++----
18 files changed, 181 insertions(+), 209 deletions(-)
diff --git a/src/deh_io.c b/src/deh_io.c
index e8beb438..31fde9f1 100644
--- a/src/deh_io.c
+++ b/src/deh_io.c
@@ -120,7 +120,7 @@ deh_context_t *DEH_OpenLump(int lumpnum)
context->input_buffer_pos = 0;
context->filename = malloc(9);
- M_StringCopy(context->filename, lumpinfo[lumpnum].name, 9);
+ M_StringCopy(context->filename, lumpinfo[lumpnum]->name, 9);
return context;
}
diff --git a/src/doom/d_main.c b/src/doom/d_main.c
index 14e58d75..3dd6e4ff 100644
--- a/src/doom/d_main.c
+++ b/src/doom/d_main.c
@@ -739,12 +739,12 @@ void D_IdentifyVersion(void)
for (i=0; i<numlumps; ++i)
{
- if (!strncasecmp(lumpinfo[i].name, "MAP01", 8))
+ if (!strncasecmp(lumpinfo[i]->name, "MAP01", 8))
{
gamemission = doom2;
break;
}
- else if (!strncasecmp(lumpinfo[i].name, "E1M1", 8))
+ else if (!strncasecmp(lumpinfo[i]->name, "E1M1", 8))
{
gamemission = doom;
break;
@@ -1531,7 +1531,7 @@ void D_DoomMain (void)
if (D_AddFile(file))
{
- M_StringCopy(demolumpname, lumpinfo[numlumps - 1].name,
+ M_StringCopy(demolumpname, lumpinfo[numlumps - 1]->name,
sizeof(demolumpname));
}
else
@@ -1566,7 +1566,7 @@ void D_DoomMain (void)
for (i = numiwadlumps; i < numlumps; ++i)
{
- if (!strncmp(lumpinfo[i].name, "DEHACKED", 8))
+ if (!strncmp(lumpinfo[i]->name, "DEHACKED", 8))
{
DEH_LoadLump(i, false, false);
loaded++;
diff --git a/src/doom/r_data.c b/src/doom/r_data.c
index 2d4b65bb..0de12185 100644
--- a/src/doom/r_data.c
+++ b/src/doom/r_data.c
@@ -832,7 +832,7 @@ void R_PrecacheLevel (void)
if (flatpresent[i])
{
lump = firstflat + i;
- flatmemory += lumpinfo[lump].size;
+ flatmemory += lumpinfo[lump]->size;
W_CacheLumpNum(lump, PU_CACHE);
}
}
@@ -869,7 +869,7 @@ void R_PrecacheLevel (void)
for (j=0 ; j<texture->patchcount ; j++)
{
lump = texture->patches[j].patch;
- texturememory += lumpinfo[lump].size;
+ texturememory += lumpinfo[lump]->size;
W_CacheLumpNum(lump , PU_CACHE);
}
}
@@ -898,7 +898,7 @@ void R_PrecacheLevel (void)
for (k=0 ; k<8 ; k++)
{
lump = firstspritelump + sf->lump[k];
- spritememory += lumpinfo[lump].size;
+ spritememory += lumpinfo[lump]->size;
W_CacheLumpNum(lump , PU_CACHE);
}
}
diff --git a/src/doom/r_things.c b/src/doom/r_things.c
index 764b1d7e..a62cfde1 100644
--- a/src/doom/r_things.c
+++ b/src/doom/r_things.c
@@ -208,22 +208,22 @@ void R_InitSpriteDefs (char** namelist)
// filling in the frames for whatever is found
for (l=start+1 ; l<end ; l++)
{
- if (!strncasecmp(lumpinfo[l].name, spritename, 4))
+ if (!strncasecmp(lumpinfo[l]->name, spritename, 4))
{
- frame = lumpinfo[l].name[4] - 'A';
- rotation = lumpinfo[l].name[5] - '0';
+ frame = lumpinfo[l]->name[4] - 'A';
+ rotation = lumpinfo[l]->name[5] - '0';
if (modifiedgame)
- patched = W_GetNumForName (lumpinfo[l].name);
+ patched = W_GetNumForName (lumpinfo[l]->name);
else
patched = l;
R_InstallSpriteLump (patched, frame, rotation, false);
- if (lumpinfo[l].name[6])
+ if (lumpinfo[l]->name[6])
{
- frame = lumpinfo[l].name[6] - 'A';
- rotation = lumpinfo[l].name[7] - '0';
+ frame = lumpinfo[l]->name[6] - 'A';
+ rotation = lumpinfo[l]->name[7] - '0';
R_InstallSpriteLump (l, frame, rotation, true);
}
}
diff --git a/src/heretic/d_main.c b/src/heretic/d_main.c
index 6521aff3..3c88de2c 100644
--- a/src/heretic/d_main.c
+++ b/src/heretic/d_main.c
@@ -1018,7 +1018,7 @@ void D_DoomMain(void)
if (D_AddFile(file))
{
- M_StringCopy(demolumpname, lumpinfo[numlumps - 1].name,
+ M_StringCopy(demolumpname, lumpinfo[numlumps - 1]->name,
sizeof(demolumpname));
}
else
diff --git a/src/heretic/r_data.c b/src/heretic/r_data.c
index 870f5c32..b7f51fb0 100644
--- a/src/heretic/r_data.c
+++ b/src/heretic/r_data.c
@@ -671,7 +671,7 @@ void R_PrecacheLevel(void)
if (flatpresent[i])
{
lump = firstflat + i;
- flatmemory += lumpinfo[lump].size;
+ flatmemory += lumpinfo[lump]->size;
W_CacheLumpNum(lump, PU_CACHE);
}
@@ -701,7 +701,7 @@ void R_PrecacheLevel(void)
for (j = 0; j < texture->patchcount; j++)
{
lump = texture->patches[j].patch;
- texturememory += lumpinfo[lump].size;
+ texturememory += lumpinfo[lump]->size;
W_CacheLumpNum(lump, PU_CACHE);
}
}
@@ -731,7 +731,7 @@ void R_PrecacheLevel(void)
for (k = 0; k < 8; k++)
{
lump = firstspritelump + sf->lump[k];
- spritememory += lumpinfo[lump].size;
+ spritememory += lumpinfo[lump]->size;
W_CacheLumpNum(lump, PU_CACHE);
}
}
diff --git a/src/heretic/r_things.c b/src/heretic/r_things.c
index 489c94bc..0e759e5d 100644
--- a/src/heretic/r_things.c
+++ b/src/heretic/r_things.c
@@ -175,15 +175,15 @@ void R_InitSpriteDefs(char **namelist)
// scan the lumps, filling in the frames for whatever is found
//
for (l = start + 1; l < end; l++)
- if (!strncasecmp(lumpinfo[l].name, spritename, 4))
+ if (!strncasecmp(lumpinfo[l]->name, spritename, 4))
{
- frame = lumpinfo[l].name[4] - 'A';
- rotation = lumpinfo[l].name[5] - '0';
+ frame = lumpinfo[l]->name[4] - 'A';
+ rotation = lumpinfo[l]->name[5] - '0';
R_InstallSpriteLump(l, frame, rotation, false);
- if (lumpinfo[l].name[6])
+ if (lumpinfo[l]->name[6])
{
- frame = lumpinfo[l].name[6] - 'A';
- rotation = lumpinfo[l].name[7] - '0';
+ frame = lumpinfo[l]->name[6] - 'A';
+ rotation = lumpinfo[l]->name[7] - '0';
R_InstallSpriteLump(l, frame, rotation, true);
}
}
diff --git a/src/hexen/h2_main.c b/src/hexen/h2_main.c
index 47c5e286..188b76bb 100644
--- a/src/hexen/h2_main.c
+++ b/src/hexen/h2_main.c
@@ -663,7 +663,7 @@ static void HandleArgs(void)
if (W_AddFile(file) != NULL)
{
- M_StringCopy(demolumpname, lumpinfo[numlumps - 1].name,
+ M_StringCopy(demolumpname, lumpinfo[numlumps - 1]->name,
sizeof(demolumpname));
}
else
diff --git a/src/hexen/r_data.c b/src/hexen/r_data.c
index e99ecc21..311d8e8b 100644
--- a/src/hexen/r_data.c
+++ b/src/hexen/r_data.c
@@ -627,7 +627,7 @@ void R_PrecacheLevel(void)
if (flatpresent[i])
{
lump = firstflat + i;
- flatmemory += lumpinfo[lump].size;
+ flatmemory += lumpinfo[lump]->size;
W_CacheLumpNum(lump, PU_CACHE);
}
@@ -658,7 +658,7 @@ void R_PrecacheLevel(void)
for (j = 0; j < texture->patchcount; j++)
{
lump = texture->patches[j].patch;
- texturememory += lumpinfo[lump].size;
+ texturememory += lumpinfo[lump]->size;
W_CacheLumpNum(lump, PU_CACHE);
}
}
@@ -688,7 +688,7 @@ void R_PrecacheLevel(void)
for (k = 0; k < 8; k++)
{
lump = firstspritelump + sf->lump[k];
- spritememory += lumpinfo[lump].size;
+ spritememory += lumpinfo[lump]->size;
W_CacheLumpNum(lump, PU_CACHE);
}
}
diff --git a/src/hexen/r_things.c b/src/hexen/r_things.c
index 9d1cb6b5..33ad92db 100644
--- a/src/hexen/r_things.c
+++ b/src/hexen/r_things.c
@@ -178,15 +178,15 @@ void R_InitSpriteDefs(char **namelist)
// scan the lumps, filling in the frames for whatever is found
//
for (l = start + 1; l < end; l++)
- if (!strncmp(lumpinfo[l].name, namelist[i], 4))
+ if (!strncmp(lumpinfo[l]->name, namelist[i], 4))
{
- frame = lumpinfo[l].name[4] - 'A';
- rotation = lumpinfo[l].name[5] - '0';
+ frame = lumpinfo[l]->name[4] - 'A';
+ rotation = lumpinfo[l]->name[5] - '0';
R_InstallSpriteLump(l, frame, rotation, false);
- if (lumpinfo[l].name[6])
+ if (lumpinfo[l]->name[6])
{
- frame = lumpinfo[l].name[6] - 'A';
- rotation = lumpinfo[l].name[7] - '0';
+ frame = lumpinfo[l]->name[6] - 'A';
+ rotation = lumpinfo[l]->name[7] - '0';
R_InstallSpriteLump(l, frame, rotation, true);
}
}
diff --git a/src/i_sdlmusic.c b/src/i_sdlmusic.c
index 80bc49ab..416fbf95 100644
--- a/src/i_sdlmusic.c
+++ b/src/i_sdlmusic.c
@@ -752,7 +752,7 @@ static void DumpSubstituteConfig(char *filename)
for (lumpnum = 0; lumpnum < numlumps; ++lumpnum)
{
- strncpy(name, lumpinfo[lumpnum].name, 8);
+ strncpy(name, lumpinfo[lumpnum]->name, 8);
name[8] = '\0';
if (!IsMusicLump(lumpnum))
diff --git a/src/strife/d_main.c b/src/strife/d_main.c
index cc1a9022..d2d68759 100644
--- a/src/strife/d_main.c
+++ b/src/strife/d_main.c
@@ -1629,7 +1629,7 @@ void D_DoomMain (void)
if (D_AddFile (file))
{
- M_StringCopy(demolumpname, lumpinfo[numlumps - 1].name,
+ M_StringCopy(demolumpname, lumpinfo[numlumps - 1]->name,
sizeof(demolumpname));
}
else
diff --git a/src/strife/r_data.c b/src/strife/r_data.c
index 1cc4f478..f31e0cb5 100644
--- a/src/strife/r_data.c
+++ b/src/strife/r_data.c
@@ -938,7 +938,7 @@ void R_PrecacheLevel (void)
if (flatpresent[i])
{
lump = firstflat + i;
- flatmemory += lumpinfo[lump].size;
+ flatmemory += lumpinfo[lump]->size;
W_CacheLumpNum(lump, PU_CACHE);
}
}
@@ -975,7 +975,7 @@ void R_PrecacheLevel (void)
for (j=0 ; j<texture->patchcount ; j++)
{
lump = texture->patches[j].patch;
- texturememory += lumpinfo[lump].size;
+ texturememory += lumpinfo[lump]->size;
W_CacheLumpNum(lump , PU_CACHE);
}
}
@@ -1004,7 +1004,7 @@ void R_PrecacheLevel (void)
for (k=0 ; k<8 ; k++)
{
lump = firstspritelump + sf->lump[k];
- spritememory += lumpinfo[lump].size;
+ spritememory += lumpinfo[lump]->size;
W_CacheLumpNum(lump , PU_CACHE);
}
}
diff --git a/src/strife/r_things.c b/src/strife/r_things.c
index 6d37ca09..230b262c 100644
--- a/src/strife/r_things.c
+++ b/src/strife/r_things.c
@@ -211,22 +211,22 @@ void R_InitSpriteDefs (char** namelist)
// filling in the frames for whatever is found
for (l=start+1 ; l<end ; l++)
{
- if (!strncasecmp(lumpinfo[l].name, spritename, 4))
+ if (!strncasecmp(lumpinfo[l]->name, spritename, 4))
{
- frame = lumpinfo[l].name[4] - 'A';
- rotation = lumpinfo[l].name[5] - '0';
+ frame = lumpinfo[l]->name[4] - 'A';
+ rotation = lumpinfo[l]->name[5] - '0';
if (modifiedgame)
- patched = W_GetNumForName (lumpinfo[l].name);
+ patched = W_GetNumForName (lumpinfo[l]->name);
else
patched = l;
R_InstallSpriteLump (patched, frame, rotation, false);
- if (lumpinfo[l].name[6])
+ if (lumpinfo[l]->name[6])
{
- frame = lumpinfo[l].name[6] - 'A';
- rotation = lumpinfo[l].name[7] - '0';
+ frame = lumpinfo[l]->name[6] - 'A';
+ rotation = lumpinfo[l]->name[7] - '0';
R_InstallSpriteLump (l, frame, rotation, true);
}
}
diff --git a/src/w_checksum.c b/src/w_checksum.c
index 5933fdf9..bf959671 100644
--- a/src/w_checksum.c
+++ b/src/w_checksum.c
@@ -33,7 +33,7 @@ static int GetFileNumber(wad_file_t *handle)
int i;
int result;
- for (i=0; i<num_open_wadfiles; ++i)
+ for (i = 0; i < num_open_wadfiles; ++i)
{
if (open_wadfiles[i] == handle)
{
@@ -77,11 +77,11 @@ void W_Checksum(sha1_digest_t digest)
// Go through each entry in the WAD directory, adding information
// about each entry to the SHA1 hash.
- for (i=0; i<numlumps; ++i)
+ for (i = 0; i < numlumps; ++i)
{
- ChecksumAddLump(&sha1_context, &lumpinfo[i]);
+ ChecksumAddLump(&sha1_context, lumpinfo[i]);
}
-
+
SHA1_Final(digest, &sha1_context);
}
diff --git a/src/w_merge.c b/src/w_merge.c
index ae0975b6..100050df 100644
--- a/src/w_merge.c
+++ b/src/w_merge.c
@@ -39,7 +39,7 @@ typedef enum
typedef struct
{
- lumpinfo_t *lumps;
+ lumpinfo_t **lumps;
int numlumps;
} searchlist_t;
@@ -74,7 +74,7 @@ static int FindInList(searchlist_t *list, char *name)
for (i=0; i<list->numlumps; ++i)
{
- if (!strncasecmp(list->lumps[i].name, name, 8))
+ if (!strncasecmp(list->lumps[i]->name, name, 8))
return i;
}
@@ -352,7 +352,7 @@ static void GenerateSpriteList(void)
for (i=0; i<iwad_sprites.numlumps; ++i)
{
- AddSpriteLump(&iwad_sprites.lumps[i]);
+ AddSpriteLump(iwad_sprites.lumps[i]);
}
// Add all sprites from the PWAD
@@ -360,7 +360,7 @@ static void GenerateSpriteList(void)
for (i=0; i<pwad_sprites.numlumps; ++i)
{
- AddSpriteLump(&pwad_sprites.lumps[i]);
+ AddSpriteLump(pwad_sprites.lumps[i]);
}
}
@@ -386,13 +386,13 @@ static void GenerateSpriteList(void)
static void DoMerge(void)
{
section_t current_section;
- lumpinfo_t *newlumps;
+ lumpinfo_t **newlumps;
int num_newlumps;
int lumpindex;
int i, n;
-
+
// Can't ever have more lumps than we already have
- newlumps = malloc(sizeof(lumpinfo_t) * numlumps);
+ newlumps = calloc(numlumps, sizeof(lumpinfo_t *));
num_newlumps = 0;
// Add IWAD lumps
@@ -400,7 +400,7 @@ static void DoMerge(void)
for (i=0; i<iwad.numlumps; ++i)
{
- lumpinfo_t *lump = &iwad.lumps[i];
+ lumpinfo_t *lump = iwad.lumps[i];
switch (current_section)
{
@@ -414,7 +414,7 @@ static void DoMerge(void)
current_section = SECTION_SPRITES;
}
- newlumps[num_newlumps++] = *lump;
+ newlumps[num_newlumps++] = lump;
break;
@@ -432,7 +432,7 @@ static void DoMerge(void)
newlumps[num_newlumps++] = pwad_flats.lumps[n];
}
- newlumps[num_newlumps++] = *lump;
+ newlumps[num_newlumps++] = lump;
// back to normal reading
current_section = SECTION_NORMAL;
@@ -448,7 +448,7 @@ static void DoMerge(void)
if (lumpindex < 0)
{
- newlumps[num_newlumps++] = *lump;
+ newlumps[num_newlumps++] = lump;
}
}
@@ -460,18 +460,18 @@ static void DoMerge(void)
if (!strncasecmp(lump->name, "S_END", 8))
{
- // add all the pwad sprites
+ // add all the PWAD sprites
for (n=0; n<pwad_sprites.numlumps; ++n)
{
- if (SpriteLumpNeeded(&pwad_sprites.lumps[n]))
+ if (SpriteLumpNeeded(pwad_sprites.lumps[n]))
{
newlumps[num_newlumps++] = pwad_sprites.lumps[n];
}
}
// copy the ending
- newlumps[num_newlumps++] = *lump;
+ newlumps[num_newlumps++] = lump;
// back to normal reading
current_section = SECTION_NORMAL;
@@ -483,7 +483,7 @@ static void DoMerge(void)
if (SpriteLumpNeeded(lump))
{
- newlumps[num_newlumps++] = *lump;
+ newlumps[num_newlumps++] = lump;
}
}
@@ -496,7 +496,7 @@ static void DoMerge(void)
for (i=0; i<pwad.numlumps; ++i)
{
- lumpinfo_t *lump = &pwad.lumps[i];
+ lumpinfo_t *lump = pwad.lumps[i];
switch (current_section)
{
@@ -515,7 +515,7 @@ static void DoMerge(void)
{
// Don't include the headers of sections
- newlumps[num_newlumps++] = *lump;
+ newlumps[num_newlumps++] = lump;
}
break;
@@ -550,7 +550,6 @@ static void DoMerge(void)
free(lumpinfo);
lumpinfo = newlumps;
numlumps = num_newlumps;
-
}
void W_PrintDirectory(void)
@@ -560,8 +559,8 @@ void W_PrintDirectory(void)
// debug
for (i=0; i<numlumps; ++i)
{
- for (n=0; n<8 && lumpinfo[i].name[n] != '\0'; ++n)
- putchar(lumpinfo[i].name[n]);
+ for (n=0; n<8 && lumpinfo[i]->name[n] != '\0'; ++n)
+ putchar(lumpinfo[i]->name[n]);
putchar('\n');
}
}
@@ -579,7 +578,7 @@ void W_MergeFile(char *filename)
if (W_AddFile(filename) == NULL)
return;
- // iwad is at the start, pwad was appended to the end
+ // IWAD is at the start, PWAD was appended to the end
iwad.lumps = lumpinfo;
iwad.numlumps = old_numlumps;
@@ -606,25 +605,23 @@ static void W_NWTAddLumps(searchlist_t *list)
{
int i;
- // Go through the IWAD list given, replacing lumps with lumps of
+ // Go through the IWAD list given, replacing lumps with lumps of
// the same name from the PWAD
-
for (i=0; i<list->numlumps; ++i)
{
int index;
- index = FindInList(&pwad, list->lumps[i].name);
+ index = FindInList(&pwad, list->lumps[i]->name);
if (index > 0)
{
- memcpy(&list->lumps[i], &pwad.lumps[index],
+ memcpy(list->lumps[i], pwad.lumps[index],
sizeof(lumpinfo_t));
}
}
-
}
-// Merge sprites and flats in the way NWT does with its -af and -as
+// Merge sprites and flats in the way NWT does with its -af and -as
// command-line options.
void W_NWTMergeFile(char *filename, int flags)
@@ -638,20 +635,20 @@ void W_NWTMergeFile(char *filename, int flags)
if (W_AddFile(filename) == NULL)
return;
- // iwad is at the start, pwad was appended to the end
+ // IWAD is at the start, PWAD was appended to the end
iwad.lumps = lumpinfo;
iwad.numlumps = old_numlumps;
pwad.lumps = lumpinfo + old_numlumps;
pwad.numlumps = numlumps - old_numlumps;
-
+
// Setup sprite/flat lists
SetupLists();
// Merge in flats?
-
+
if (flags & W_NWT_MERGE_FLATS)
{
W_NWTAddLumps(&iwad_flats);
@@ -690,14 +687,14 @@ void W_NWTDashMerge(char *filename)
return;
}
- // iwad is at the start, pwad was appended to the end
+ // IWAD is at the start, PWAD was appended to the end
iwad.lumps = lumpinfo;
iwad.numlumps = old_numlumps;
pwad.lumps = lumpinfo + old_numlumps;
pwad.numlumps = numlumps - old_numlumps;
-
+
// Setup sprite/flat lists
SetupLists();
@@ -706,12 +703,12 @@ void W_NWTDashMerge(char *filename)
for (i=0; i<iwad_sprites.numlumps; ++i)
{
- if (FindInList(&pwad, iwad_sprites.lumps[i].name) >= 0)
+ if (FindInList(&pwad, iwad_sprites.lumps[i]->name) >= 0)
{
// Replace this entry with an empty string. This is what
// nwt -merge does.
- M_StringCopy(iwad_sprites.lumps[i].name, "", 8);
+ M_StringCopy(iwad_sprites.lumps[i]->name, "", 8);
}
}
diff --git a/src/w_wad.c b/src/w_wad.c
index ea684f4e..567c6cf0 100644
--- a/src/w_wad.c
+++ b/src/w_wad.c
@@ -57,16 +57,17 @@ typedef struct
//
// Location of each lump on disk.
-lumpinfo_t *lumpinfo;
+lumpinfo_t **lumpinfo;
unsigned int numlumps = 0;
// Hash table for fast lookups
-static lumpinfo_t **lumphash;
+static lumpindex_t *lumphash;
// Variables for the reload hack: filename of the PWAD to reload, and the
// lumps from WADs before the reload file, so we can resent numlumps and
// load the file again.
static wad_file_t *reloadhandle = NULL;
+static lumpinfo_t *reloadlumps = NULL;
static char *reloadname = NULL;
static int reloadlump = -1;
@@ -87,46 +88,6 @@ unsigned int W_LumpNameHash(const char *s)
return result;
}
-// Increase the size of the lumpinfo[] array to the specified size.
-static void ExtendLumpInfo(int newnumlumps)
-{
- lumpinfo_t *newlumpinfo;
- unsigned int i;
-
- newlumpinfo = calloc(newnumlumps, sizeof(lumpinfo_t));
-
- if (newlumpinfo == NULL)
- {
- I_Error ("Couldn't realloc lumpinfo");
- }
-
- // Copy over lumpinfo_t structures from the old array. If any of
- // these lumps have been cached, we need to update the user
- // pointers to the new location.
- for (i = 0; i < numlumps && i < newnumlumps; ++i)
- {
- memcpy(&newlumpinfo[i], &lumpinfo[i], sizeof(lumpinfo_t));
-
- if (newlumpinfo[i].cache != NULL)
- {
- Z_ChangeUser(newlumpinfo[i].cache, &newlumpinfo[i].cache);
- }
-
- // We shouldn't be generating a hash table until after all WADs have
- // been loaded, but just in case...
- if (lumpinfo[i].next != NULL)
- {
- int nextlumpnum = lumpinfo[i].next - lumpinfo;
- newlumpinfo[i].next = &newlumpinfo[nextlumpnum];
- }
- }
-
- // All done.
- free(lumpinfo);
- lumpinfo = newlumpinfo;
- numlumps = newnumlumps;
-}
-
//
// LUMP BASED ROUTINES.
//
@@ -143,14 +104,14 @@ static void ExtendLumpInfo(int newnumlumps)
wad_file_t *W_AddFile (char *filename)
{
wadinfo_t header;
- lumpinfo_t *lump_p;
- unsigned int i;
+ lumpindex_t i;
wad_file_t *wad_file;
int length;
int startlump;
filelump_t *fileinfo;
filelump_t *filerover;
- int newnumlumps;
+ lumpinfo_t *filelumps;
+ int numfilelumps;
// If the filename begins with a ~, it indicates that we should use the
// reload hack.
@@ -180,15 +141,6 @@ wad_file_t *W_AddFile (char *filename)
return NULL;
}
- // If this is the reload file, we need to save the file handle so that we
- // can close it later on when we do a reload.
- if (reloadname)
- {
- reloadhandle = wad_file;
- }
-
- newnumlumps = numlumps;
-
if (strcasecmp(filename+strlen(filename)-3 , "wad" ) )
{
// single lump file
@@ -206,9 +158,9 @@ wad_file_t *W_AddFile (char *filename)
// extension).
M_ExtractFileBase (filename, fileinfo->name);
- newnumlumps++;
+ numfilelumps = 1;
}
- else
+ else
{
// WAD file
W_Read(wad_file, 0, &header, sizeof(header));
@@ -221,8 +173,8 @@ wad_file_t *W_AddFile (char *filename)
I_Error ("Wad file %s doesn't have IWAD "
"or PWAD id\n", filename);
}
-
- // ???modifiedgame = true;
+
+ // ???modifiedgame = true;
}
header.numlumps = LONG(header.numlumps);
@@ -231,26 +183,36 @@ wad_file_t *W_AddFile (char *filename)
fileinfo = Z_Malloc(length, PU_STATIC, 0);
W_Read(wad_file, header.infotableofs, fileinfo, length);
- newnumlumps += header.numlumps;
+ numfilelumps = header.numlumps;
}
// Increase size of numlumps array to accomodate the new file.
- startlump = numlumps;
- ExtendLumpInfo(newnumlumps);
+ filelumps = calloc(numfilelumps, sizeof(lumpinfo_t));
+ if (filelumps == NULL)
+ {
+ I_Error("Failed to allocate array for lumps from new file.");
+ }
- lump_p = &lumpinfo[startlump];
+ startlump = numlumps;
+ numlumps += numfilelumps;
+ lumpinfo = realloc(lumpinfo, numlumps * sizeof(lumpinfo_t *));
+ if (lumpinfo == NULL)
+ {
+ I_Error("Failed to increase lumpinfo[] array size.");
+ }
filerover = fileinfo;
- for (i=startlump; i<numlumps; ++i)
+ for (i = startlump; i < numlumps; ++i)
{
- lump_p->wad_file = wad_file;
- lump_p->position = LONG(filerover->filepos);
- lump_p->size = LONG(filerover->size);
+ lumpinfo_t *lump_p = &filelumps[i - startlump];
+ lump_p->wad_file = wad_file;
+ lump_p->position = LONG(filerover->filepos);
+ lump_p->size = LONG(filerover->size);
lump_p->cache = NULL;
- strncpy(lump_p->name, filerover->name, 8);
+ strncpy(lump_p->name, filerover->name, 8);
+ lumpinfo[i] = lump_p;
- ++lump_p;
++filerover;
}
@@ -262,6 +224,14 @@ wad_file_t *W_AddFile (char *filename)
lumphash = NULL;
}
+ // If this is the reload file, we need to save some details about the
+ // file so that we can close it later on when we do a reload.
+ if (reloadname)
+ {
+ reloadhandle = wad_file;
+ reloadlumps = filelumps;
+ }
+
return wad_file;
}
@@ -282,38 +252,37 @@ int W_NumLumps (void)
// Returns -1 if name not found.
//
-int W_CheckNumForName (char* name)
+lumpindex_t W_CheckNumForName(char* name)
{
- lumpinfo_t *lump_p;
- int i;
+ lumpindex_t i;
// Do we have a hash table yet?
if (lumphash != NULL)
{
int hash;
-
+
// We do! Excellent.
hash = W_LumpNameHash(name) % numlumps;
-
- for (lump_p = lumphash[hash]; lump_p != NULL; lump_p = lump_p->next)
+
+ for (i = lumphash[hash]; i != -1; i = lumpinfo[i]->next)
{
- if (!strncasecmp(lump_p->name, name, 8))
+ if (!strncasecmp(lumpinfo[i]->name, name, 8))
{
- return lump_p - lumpinfo;
+ return i;
}
}
- }
+ }
else
{
// We don't have a hash table generate yet. Linear search :-(
- //
+ //
// scan backwards so patch lump files take precedence
- for (i=numlumps-1; i >= 0; --i)
+ for (i = numlumps - 1; i >= 0; --i)
{
- if (!strncasecmp(lumpinfo[i].name, name, 8))
+ if (!strncasecmp(lumpinfo[i]->name, name, 8))
{
return i;
}
@@ -332,12 +301,12 @@ int W_CheckNumForName (char* name)
// W_GetNumForName
// Calls W_CheckNumForName, but bombs out if not found.
//
-int W_GetNumForName (char* name)
+lumpindex_t W_GetNumForName(char* name)
{
- int i;
+ lumpindex_t i;
i = W_CheckNumForName (name);
-
+
if (i < 0)
{
I_Error ("W_GetNumForName: %s not found!", name);
@@ -351,14 +320,14 @@ int W_GetNumForName (char* name)
// W_LumpLength
// Returns the buffer size needed to load the given lump.
//
-int W_LumpLength (unsigned int lump)
+int W_LumpLength(lumpindex_t lump)
{
if (lump >= numlumps)
{
I_Error ("W_LumpLength: %i >= numlumps", lump);
}
- return lumpinfo[lump].size;
+ return lumpinfo[lump]->size;
}
@@ -368,29 +337,29 @@ int W_LumpLength (unsigned int lump)
// Loads the lump into the given buffer,
// which must be >= W_LumpLength().
//
-void W_ReadLump(unsigned int lump, void *dest)
+void W_ReadLump(lumpindex_t lump, void *dest)
{
int c;
lumpinfo_t *l;
-
+
if (lump >= numlumps)
{
- I_Error ("W_ReadLump: %i >= numlumps", lump);
+ I_Error ("W_ReadLump: %i >= numlumps", lump);
}
- l = lumpinfo+lump;
-
- I_BeginRead ();
-
+ l = lumpinfo[lump];
+
+ I_BeginRead();
+
c = W_Read(l->wad_file, l->position, dest, l->size);
if (c < l->size)
{
- I_Error ("W_ReadLump: only read %i of %i on lump %i",
- c, l->size, lump);
+ I_Error("W_ReadLump: only read %i of %i on lump %i",
+ c, l->size, lump);
}
- I_EndRead ();
+ I_EndRead();
}
@@ -408,7 +377,7 @@ void W_ReadLump(unsigned int lump, void *dest)
// when no longer needed (do not use Z_ChangeTag).
//
-void *W_CacheLumpNum(int lumpnum, int tag)
+void *W_CacheLumpNum(lumpindex_t lumpnum, int tag)
{
byte *result;
lumpinfo_t *lump;
@@ -418,7 +387,7 @@ void *W_CacheLumpNum(int lumpnum, int tag)
I_Error ("W_CacheLumpNum: %i >= numlumps", lumpnum);
}
- lump = &lumpinfo[lumpnum];
+ lump = lumpinfo[lumpnum];
// Get the pointer to return. If the lump is in a memory-mapped
// file, we can just return a pointer to within the memory-mapped
@@ -470,7 +439,7 @@ void *W_CacheLumpName(char *name, int tag)
// complicated ...
//
-void W_ReleaseLumpNum(int lumpnum)
+void W_ReleaseLumpNum(lumpindex_t lumpnum)
{
lumpinfo_t *lump;
@@ -479,7 +448,7 @@ void W_ReleaseLumpNum(int lumpnum)
I_Error ("W_ReleaseLumpNum: %i >= numlumps", lumpnum);
}
- lump = &lumpinfo[lumpnum];
+ lump = lumpinfo[lumpnum];
if (lump->wad_file->mapped != NULL)
{
@@ -566,7 +535,7 @@ void W_Profile (void)
void W_GenerateHashTable(void)
{
- unsigned int i;
+ lumpindex_t i;
// Free the old hash table, if there is one:
if (lumphash != NULL)
@@ -577,19 +546,23 @@ void W_GenerateHashTable(void)
// Generate hash table
if (numlumps > 0)
{
- lumphash = Z_Malloc(sizeof(lumpinfo_t *) * numlumps, PU_STATIC, NULL);
- memset(lumphash, 0, sizeof(lumpinfo_t *) * numlumps);
+ lumphash = Z_Malloc(sizeof(lumpindex_t) * numlumps, PU_STATIC, NULL);
- for (i=0; i<numlumps; ++i)
+ for (i = 0; i < numlumps; ++i)
+ {
+ lumphash[i] = -1;
+ }
+
+ for (i = 0; i < numlumps; ++i)
{
unsigned int hash;
- hash = W_LumpNameHash(lumpinfo[i].name) % numlumps;
+ hash = W_LumpNameHash(lumpinfo[i]->name) % numlumps;
// Hook into the hash table
- lumpinfo[i].next = lumphash[hash];
- lumphash[hash] = &lumpinfo[i];
+ lumpinfo[i]->next = lumphash[hash];
+ lumphash[hash] = i;
}
}
@@ -605,7 +578,7 @@ void W_GenerateHashTable(void)
void W_Reload(void)
{
char *filename;
- int i;
+ lumpindex_t i;
if (reloadname == NULL)
{
@@ -615,9 +588,9 @@ void W_Reload(void)
// We must free any lumps being cached from the PWAD we're about to reload:
for (i = reloadlump; i < numlumps; ++i)
{
- if (lumpinfo[i].cache != NULL)
+ if (lumpinfo[i]->cache != NULL)
{
- Z_Free(lumpinfo[i].cache);
+ Z_Free(lumpinfo[i]->cache);
}
}
@@ -628,6 +601,8 @@ void W_Reload(void)
filename = reloadname;
W_CloseFile(reloadhandle);
+ free(reloadlumps);
+
reloadname = NULL;
reloadlump = -1;
reloadhandle = NULL;
@@ -656,7 +631,7 @@ static const struct
void W_CheckCorrectIWAD(GameMission_t mission)
{
int i;
- int lumpnum;
+ lumpindex_t lumpnum;
for (i = 0; i < arrlen(unique_lumps); ++i)
{
diff --git a/src/w_wad.h b/src/w_wad.h
index e5dc18b3..9587283f 100644
--- a/src/w_wad.h
+++ b/src/w_wad.h
@@ -37,6 +37,7 @@
//
typedef struct lumpinfo_s lumpinfo_t;
+typedef int lumpindex_t;
struct lumpinfo_s
{
@@ -47,32 +48,31 @@ struct lumpinfo_s
void *cache;
// Used for hash table lookups
-
- lumpinfo_t *next;
+ lumpindex_t next;
};
-extern lumpinfo_t *lumpinfo;
+extern lumpinfo_t **lumpinfo;
extern unsigned int numlumps;
-wad_file_t *W_AddFile (char *filename);
-void W_Reload (void);
+wad_file_t *W_AddFile(char *filename);
+void W_Reload(void);
-int W_CheckNumForName (char* name);
-int W_GetNumForName (char* name);
+lumpindex_t W_CheckNumForName(char *name);
+lumpindex_t W_GetNumForName(char *name);
-int W_LumpLength (unsigned int lump);
-void W_ReadLump (unsigned int lump, void *dest);
+int W_LumpLength(lumpindex_t lump);
+void W_ReadLump(lumpindex_t lump, void *dest);
-void* W_CacheLumpNum (int lump, int tag);
-void* W_CacheLumpName (char* name, int tag);
+void *W_CacheLumpNum(lumpindex_t lump, int tag);
+void *W_CacheLumpName(char *name, int tag);
-void W_GenerateHashTable(void);
+void W_GenerateHashTable(void);
extern unsigned int W_LumpNameHash(const char *s);
-void W_ReleaseLumpNum(int lump);
-void W_ReleaseLumpName(char *name);
+void W_ReleaseLumpNum(lumpindex_t lump);
+void W_ReleaseLumpName(char *name);
void W_CheckCorrectIWAD(GameMission_t mission);