- Did some minor reorganization of code in r_data.cpp (mostly to make

handling of textures easier in GZDoom.)
- Did some preparations to allow loading folders on the HD into the lump
  directory.


SVN r298 (trunk)
This commit is contained in:
Christoph Oelckers 2006-08-17 22:10:50 +00:00
parent f66b7de8c8
commit aef5df6628
9 changed files with 262 additions and 135 deletions

View file

@ -1,4 +1,10 @@
August 17, 2006 (Changes by Graf Zahl)
- Added a check to the map loader to check whether the map label
is in the same WAD as the following lump.
- Did some minor reorganization of code in r_data.cpp (mostly to make
handling of textures easier in GZDoom.)
- Did some preparations to allow loading folders on the HD into the lump
directory.
- Took MF2_WINDTHRUST off AMorphedMonster. This is something that should not
be a default setting.
- Moved a_artiegg.cpp to g_shared and renamed it to a_morph.cpp to better reflect

View file

@ -271,7 +271,19 @@ MapData *P_OpenMapData(const char * mapname)
if (lump_name > lump_wad && lump_name > lump_map && lump_name != -1)
{
map->file = Wads.GetFileReader(Wads.GetLumpFile (lump_name));
int lumpfile=Wads.GetLumpFile(lump_name);
int nextfile=Wads.GetLumpFile(lump_name+1);
if (lumpfile != nextfile)
{
// The following lump is from a different file so whatever this is,
// it is not a multi-lump Doom level.
return map;
}
// This case can only happen if the lump is inside a real WAD file.
// As such any special handling for other types of lumps is skipped.
map->file = Wads.GetFileReader(lumpfile);
map->CloseOnDestruct = false;
map->lumpnum = lump_name;

View file

@ -37,10 +37,8 @@
#include <stddef.h>
#include <malloc.h>
#include <stdio.h>
extern "C"
{
#include <jpeglib.h>
}
#include "r_jpeg.h"
#include "i_system.h"
#include "m_alloc.h"
@ -235,9 +233,10 @@ int FTextureManager::AddTexture (FTexture *texture)
return trans;
}
// Examines the lump contents to decide what type of texture to create,
// creates the texture, and adds it to the manager.
int FTextureManager::CreateTexture (int lumpnum, int usetype)
// and creates the texture.
FTexture * FTextureManager::DoCreateTexture (int lumpnum, int usetype)
{
FTexture *out = NULL;
enum { t_patch, t_raw, t_imgz, t_png } type = t_patch;
@ -252,7 +251,7 @@ int FTextureManager::CreateTexture (int lumpnum, int usetype)
// 13 is the minimum length of anything valid (i.e a 1x1 pixel Doom patch.)
if (lumpnum < 0 || Wads.LumpLength(lumpnum)<13)
{
return -1;
return NULL;
}
else
{
@ -272,11 +271,11 @@ int FTextureManager::CreateTexture (int lumpnum, int usetype)
// first 4 bytes match, but later bytes don't, we assume it's
// a corrupt PNG.)
data.Read (first4bytes.b, 4);
if (first4bytes.dw != MAKE_ID(13,10,26,10)) return -1;
if (first4bytes.dw != MAKE_ID(13,10,26,10)) return NULL;
data.Read (first4bytes.b, 4);
if (first4bytes.dw != MAKE_ID(0,0,0,13)) return -1;
if (first4bytes.dw != MAKE_ID(0,0,0,13)) return NULL;
data.Read (first4bytes.b, 4);
if (first4bytes.dw != MAKE_ID('I','H','D','R')) return -1;
if (first4bytes.dw != MAKE_ID('I','H','D','R')) return NULL;
// The PNG looks valid so far. Check the IHDR to make sure it's a
// type of PNG we support.
@ -285,15 +284,15 @@ int FTextureManager::CreateTexture (int lumpnum, int usetype)
if (compression != 0 || filter != 0 || interlace > 1)
{
return -1;
return NULL;
}
if (!((1 << colortype) & 0x5D))
{
return -1;
return NULL;
}
if (!((1 << bitdepth) & 0x116))
{
return -1;
return NULL;
}
// Just for completeness, make sure the PNG has something more than an
@ -305,7 +304,7 @@ int FTextureManager::CreateTexture (int lumpnum, int usetype)
data.Read (first4bytes.b, 4);
if (first4bytes.dw == MAKE_ID('I','E','N','D'))
{
return -1;
return NULL;
}
}
@ -323,25 +322,25 @@ int FTextureManager::CreateTexture (int lumpnum, int usetype)
{
if (data.Read (first4bytes.w, 2) != 2)
{
return -1;
return NULL;
}
data.Seek (BigShort(first4bytes.w[0]) - 2, SEEK_CUR);
if (data.Read (first4bytes.b + 2, 2) != 2 || first4bytes.b[2] != 0xFF)
{
return -1;
return NULL;
}
}
if (data.Read (first4bytes.b, 3) != 3)
{
return -1;
return NULL;
}
if (BigShort (first4bytes.w[0]) <5)
{
return -1;
return NULL;
}
if (data.Read (first4bytes.b, 4) != 4)
{
return -1;
return NULL;
}
type = t_png;
out = new FJPEGTexture (lumpnum, BigShort(first4bytes.w[1]), BigShort(first4bytes.w[0]));
@ -349,7 +348,7 @@ int FTextureManager::CreateTexture (int lumpnum, int usetype)
else if (usetype == FTexture::TEX_Flat)
{
// allow PNGs as flats but not Doom patches.
return -1;
return NULL;
}
else if ((gameinfo.flags & GI_PAGESARERAW) && data.GetLength() == 64000)
{
@ -438,8 +437,16 @@ int FTextureManager::CreateTexture (int lumpnum, int usetype)
{
out->UseType = usetype;
}
return AddTexture (out);
}
return out;
}
// Calls DoCreateTexture and adds the texture to the manager.
int FTextureManager::CreateTexture (int lumpnum, int usetype)
{
FTexture *out = DoCreateTexture(lumpnum, usetype);
if (out != NULL) return AddTexture (out);
return -1;
}
@ -2138,13 +2145,7 @@ void FPNGTexture::MakeTexture ()
}
}
struct FLumpSourceMgr : public jpeg_source_mgr
{
FWadLump &Lump;
JOCTET Buffer[4096];
bool StartOfFile;
FLumpSourceMgr (FWadLump &lump, j_decompress_ptr cinfo)
FLumpSourceMgr::FLumpSourceMgr (FileReader *lump, j_decompress_ptr cinfo)
: Lump (lump)
{
cinfo->src = this;
@ -2157,15 +2158,15 @@ struct FLumpSourceMgr : public jpeg_source_mgr
next_input_byte = NULL;
}
static void InitSource (j_decompress_ptr cinfo)
void FLumpSourceMgr::InitSource (j_decompress_ptr cinfo)
{
((FLumpSourceMgr *)(cinfo->src))->StartOfFile = true;
}
static boolean FillInputBuffer (j_decompress_ptr cinfo)
boolean FLumpSourceMgr::FillInputBuffer (j_decompress_ptr cinfo)
{
FLumpSourceMgr *me = (FLumpSourceMgr *)(cinfo->src);
long nbytes = me->Lump.Read (me->Buffer, sizeof(me->Buffer));
long nbytes = me->Lump->Read (me->Buffer, sizeof(me->Buffer));
if (nbytes <= 0)
{
@ -2179,7 +2180,7 @@ struct FLumpSourceMgr : public jpeg_source_mgr
return TRUE;
}
static void SkipInputData (j_decompress_ptr cinfo, long num_bytes)
void FLumpSourceMgr::SkipInputData (j_decompress_ptr cinfo, long num_bytes)
{
FLumpSourceMgr *me = (FLumpSourceMgr *)(cinfo->src);
if (num_bytes <= (long)me->bytes_in_buffer)
@ -2190,23 +2191,22 @@ struct FLumpSourceMgr : public jpeg_source_mgr
else
{
num_bytes -= (long)me->bytes_in_buffer;
me->Lump.Seek (num_bytes, SEEK_CUR);
me->Lump->Seek (num_bytes, SEEK_CUR);
FillInputBuffer (cinfo);
}
}
static void TermSource (j_decompress_ptr cinfo)
void FLumpSourceMgr::TermSource (j_decompress_ptr cinfo)
{
}
};
static void JPEG_ErrorExit (j_common_ptr cinfo)
void JPEG_ErrorExit (j_common_ptr cinfo)
{
(*cinfo->err->output_message) (cinfo);
throw -1;
}
static void JPEG_OutputMessage (j_common_ptr cinfo)
void JPEG_OutputMessage (j_common_ptr cinfo)
{
char buffer[JMSG_LENGTH_MAX];
@ -2299,7 +2299,7 @@ void FJPEGTexture::MakeTexture ()
jpeg_create_decompress(&cinfo);
try
{
FLumpSourceMgr sourcemgr(lump, &cinfo);
FLumpSourceMgr sourcemgr(&lump, &cinfo);
jpeg_read_header(&cinfo, TRUE);
if (!((cinfo.out_color_space == JCS_RGB && cinfo.num_components == 3) ||
(cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) ||

View file

@ -29,6 +29,7 @@
#include "v_video.h"
// A texture that doesn't really exist
class FDummyTexture : public FTexture
{
@ -210,6 +211,7 @@ protected:
};
// A JPEG image
class FJPEGTexture : public FTexture
{

View file

@ -731,6 +731,7 @@ public:
void AddTiles (void *tileFile);
void AddExtraTextures (); // Adds patches in the ns_newtextures namespace
static FTexture *DoCreateTexture (int lumpnum, int usetype=FTexture::TEX_Any);
int CreateTexture (int lumpnum, int usetype=FTexture::TEX_Any); // Also calls AddTexture
int AddTexture (FTexture *texture);
int AddPatch (const char *patchname, int namespc=0);

29
src/r_jpeg.h Normal file
View file

@ -0,0 +1,29 @@
#ifndef __R_JPEG_H
#define __R_JPEG_H
extern "C"
{
#include <jpeglib.h>
}
#include "files.h"
struct FLumpSourceMgr : public jpeg_source_mgr
{
FileReader *Lump;
JOCTET Buffer[4096];
bool StartOfFile;
FLumpSourceMgr (FileReader *lump, j_decompress_ptr cinfo);
static void InitSource (j_decompress_ptr cinfo);
static boolean FillInputBuffer (j_decompress_ptr cinfo);
static void SkipInputData (j_decompress_ptr cinfo, long num_bytes);
static void TermSource (j_decompress_ptr cinfo);
};
void JPEG_ErrorExit (j_common_ptr cinfo);
void JPEG_OutputMessage (j_common_ptr cinfo);
#endif

View file

@ -100,6 +100,7 @@ enum
LUMPF_COMPRESSED = 2, // Zip-compressed
LUMPF_ZIPFILE = 4, // Inside a Zip file - used to enforce use of special directories insize Zips
LUMPF_NEEDFILESTART = 8, // Still need to process local file header to find file start inside a zip
LUMPF_EXTERNAL = 16, // Lump is from an external file that won't be kept open permanently
};
class FWadCollection::WadFileRecord : public FileReader
@ -161,7 +162,7 @@ void uppercopy (char *to, const char *from)
FWadCollection::FWadCollection ()
: FirstLumpIndex(NULL), NextLumpIndex(NULL),
FirstLumpIndex_FullName(NULL), NextLumpIndex_FullName(NULL),
LumpInfo(NULL), Wads(NULL), NumLumps(0), NumWads(0)
NumLumps(0)
{
}
@ -187,27 +188,20 @@ FWadCollection::~FWadCollection ()
delete[] NextLumpIndex_FullName;
NextLumpIndex_FullName = NULL;
}
if (LumpInfo != NULL)
{
for (DWORD i = 0; i < NumLumps; ++i)
for (DWORD i = 0; i < LumpInfo.Size(); ++i)
{
if (LumpInfo[i].fullname != NULL)
{
delete[] LumpInfo[i].fullname;
}
}
free (LumpInfo);
LumpInfo = NULL;
}
if (Wads != NULL)
{
for (DWORD i = 0; i < NumWads; ++i)
LumpInfo.Clear();
for (DWORD i = 0; i < Wads.Size(); ++i)
{
delete Wads[i];
}
free (Wads);
Wads = NULL;
}
Wads.Clear();
}
//==========================================================================
@ -227,9 +221,9 @@ void FWadCollection::InitMultipleFiles (wadlist_t **filenames)
// open all the files, load headers, and count lumps
numfiles = 0;
NumWads = 0;
Wads.Clear();
LumpInfo.Clear();
NumLumps = 0;
LumpInfo = NULL; // will be realloced as lumps are added
while (*filenames)
{
@ -276,6 +270,28 @@ void FWadCollection::InitMultipleFiles (wadlist_t **filenames)
InitHashChains ();
}
//-----------------------------------------------------------------------
//
// Adds an external file to the lump list but not to the hash chains
// It's just a simple means to assign a lump number to some file so that
// the texture manager can read from it.
//
//-----------------------------------------------------------------------
int FWadCollection::AddExternalFile(const char *filename)
{
LumpRecord lump;
lump.fullname = copystring(filename);
lump.name[0]=0;
lump.wadnum=-1;
lump.flags = LUMPF_EXTERNAL;
lump.position = 0;
lump.namespc = ns_global;
lump.compressedsize = 0;
return LumpInfo.Push(lump);
}
#define BUFREADCOMMENT (0x400)
//-----------------------------------------------------------------------
@ -421,7 +437,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
BloodCrypt (lumps, header.rff.DirOfs, header.rff.NumLumps * sizeof(rfflump_t));
NumLumps += header.rff.NumLumps;
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
LumpInfo.Resize(NumLumps);
lump_p = &LumpInfo[startlump];
for (i = 0, rff_p = lumps; i < header.rff.NumLumps; ++i, ++rff_p)
@ -443,7 +459,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
uppercopy (lump_p->name, rff_p->Name);
lump_p->name[8] = 0;
lump_p->wadnum = (WORD)NumWads;
lump_p->wadnum = (WORD)Wads.Size();
lump_p->position = LittleLong(rff_p->FilePos);
lump_p->size = LittleLong(rff_p->Size);
lump_p->flags = (rff_p->Flags & 0x10) >> 4;
@ -475,12 +491,12 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
pos = sizeof(grpinfo_t) + header.grp.NumLumps * sizeof(grplump_t);
NumLumps += header.grp.NumLumps;
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
LumpInfo.Resize(NumLumps);
lump_p = &LumpInfo[startlump];
for (i = 0, grp_p = lumps; i < header.grp.NumLumps; ++i, ++grp_p)
{
lump_p->wadnum = (WORD)NumWads;
lump_p->wadnum = (WORD)Wads.Size();
lump_p->position = pos;
lump_p->size = LittleLong(grp_p->Size);
pos += lump_p->size;
@ -521,7 +537,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
}
NumLumps += LittleShort(info.wEntryCount);
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
LumpInfo.Resize(NumLumps);
lump_p = &LumpInfo[startlump];
// Load the entire central directory. Too bad that this contains variable length entries...
@ -617,7 +633,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
memset(lump_p->name, 0, 8);
}
lump_p->wadnum = (WORD)NumWads;
lump_p->wadnum = (WORD)Wads.Size();
lump_p->flags = LittleShort(zip_fh->wCompression) == Z_DEFLATED?
LUMPF_COMPRESSED|LUMPF_ZIPFILE : LUMPF_ZIPFILE;
lump_p->compressedsize = LittleLong(zip_fh->dwCompressedSize);
@ -642,10 +658,10 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
}
// Resize the lump record array to its actual size
NumLumps -= skipped;
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
LumpInfo.Resize(NumLumps);
// Entries in Zips are sorted alphabetically.
qsort(LumpInfo + startlump, NumLumps - startlump, sizeof(LumpRecord), lumpcmp);
qsort(&LumpInfo[startlump], NumLumps - startlump, sizeof(LumpRecord), lumpcmp);
}
else
{ // This is just a single lump file
@ -664,14 +680,14 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
header.magic[0] != ZIP_ID &&
(header.magic[0] != GRP_ID_0 || header.magic[1] != GRP_ID_1 || header.magic[2] != GRP_ID_2))
{
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
LumpInfo.Resize(NumLumps);
lump_p = &LumpInfo[startlump];
for (i = startlump; i < (unsigned)NumLumps; i++, lump_p++, fileinfo++)
{
// [RH] Convert name to uppercase during copy
uppercopy (lump_p->name, fileinfo->Name);
lump_p->name[8] = 0;
lump_p->wadnum = (WORD)NumWads;
lump_p->wadnum = (WORD)Wads.Size();
lump_p->position = LittleLong(fileinfo->FilePos);
lump_p->size = LittleLong(fileinfo->Size);
lump_p->namespc = ns_global;
@ -690,11 +706,10 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
wadinfo->FirstLump = startlump;
wadinfo->LastLump = NumLumps - 1;
Wads = (WadFileRecord **)M_Realloc (Wads, (++NumWads)*sizeof(WadFileRecord*));
Wads[NumWads-1] = wadinfo;
Wads.Push(wadinfo);
// [RH] Put the Strife Teaser voices into the voices namespace
if (NumWads == IWAD_FILENUM+1 && gameinfo.gametype == GAME_Strife && gameinfo.flags & GI_SHAREWARE)
if (Wads.Size() == IWAD_FILENUM+1 && gameinfo.gametype == GAME_Strife && gameinfo.flags & GI_SHAREWARE)
{
FindStrifeTeaserVoices ();
}
@ -759,7 +774,7 @@ int FWadCollection::CheckIfWadLoaded (const char *name)
if (strrchr (name, '/') != NULL)
{
for (i = 0; i < NumWads; ++i)
for (i = 0; i < Wads.Size(); ++i)
{
if (stricmp (GetWadFullName (i), name) == 0)
{
@ -769,7 +784,7 @@ int FWadCollection::CheckIfWadLoaded (const char *name)
}
else
{
for (i = 0; i < NumWads; ++i)
for (i = 0; i < Wads.Size(); ++i)
{
if (stricmp (GetWadName (i), name) == 0)
{
@ -1066,7 +1081,7 @@ bool FWadCollection::IsMarker (const FWadCollection::LumpRecord *lump, const cha
{
// If the previous lump was of the form FF_END and this one is
// of the form F_END, ignore this as a marker
if (marker[2] == 'E' && lump > LumpInfo)
if (marker[2] == 'E' && lump > &LumpInfo[0])
{
if ((lump - 1)->name[0] == *marker &&
strncmp ((lump - 1)->name + 1, marker, 7) == 0)
@ -1204,7 +1219,7 @@ void FWadCollection::ScanForFlatHack (int startlump)
}
}
++NumLumps;
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord));
LumpInfo.Resize(NumLumps);
for (; i > j; --i)
{
LumpInfo[i+1] = LumpInfo[i];
@ -1384,7 +1399,7 @@ int FWadCollection::MergeLumps (const char *start, const char *end, int space)
}
else
// Check if this is the start of a block
if (IsMarker (LumpInfo + i, ustart))
if (IsMarker (&LumpInfo[i], ustart))
{
insideBlock = true;
markerpos = i;
@ -1415,7 +1430,7 @@ int FWadCollection::MergeLumps (const char *start, const char *end, int space)
insideBlock = false;
LumpInfo[oldlumps++] = LumpInfo[i];
}
else if (IsMarker (LumpInfo + i, uend))
else if (IsMarker (&LumpInfo[i], uend))
{
// It is the end of a block. We'll add the end marker once
// we've processed everything.
@ -1434,10 +1449,9 @@ int FWadCollection::MergeLumps (const char *start, const char *end, int space)
if (newlumps)
{
if (size_t(oldlumps + newlumps) >= NumLumps)
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, (oldlumps + newlumps + 1) * sizeof(LumpRecord) );
LumpInfo.Resize(oldlumps+newlumps+1);
memcpy (LumpInfo + oldlumps, newlumpinfos, sizeof(LumpRecord) * newlumps);
memcpy (&LumpInfo[oldlumps], newlumpinfos, sizeof(LumpRecord) * newlumps);
markerpos = oldlumps;
NumLumps = oldlumps + newlumps;
@ -1502,13 +1516,13 @@ int FWadCollection::FindLump (const char *name, int *lastlump, bool anyns)
uppercopy (name8, name);
lump_p = LumpInfo + *lastlump;
while (lump_p < LumpInfo + NumLumps)
lump_p = &LumpInfo[*lastlump];
while (lump_p < &LumpInfo[NumLumps])
{
if ((anyns || lump_p->namespc == ns_global) &&
*(__int64 *)&lump_p->name == *(__int64 *)&name8)
{
int lump = lump_p - LumpInfo;
int lump = lump_p - &LumpInfo[0];
*lastlump = lump + 1;
return lump;
}
@ -1587,7 +1601,7 @@ int FWadCollection::GetLumpNamespace (int lump) const
int FWadCollection::GetLumpFile (int lump) const
{
if ((size_t)lump >= NumLumps)
if ((size_t)lump >= LumpInfo.Size())
return -1;
return LumpInfo[lump].wadnum;
}
@ -1675,20 +1689,20 @@ FWadLump FWadCollection::OpenLumpNum (int lump)
LumpRecord *l;
WadFileRecord *wad;
if ((unsigned)lump >= (unsigned)NumLumps)
if ((unsigned)lump >= (unsigned)LumpInfo.Size())
{
I_Error ("W_MapLumpNum: %u >= NumLumps",lump);
}
l = &LumpInfo[lump];
wad = Wads[l->wadnum];
wad = l->wadnum >= 0? Wads[l->wadnum] : NULL;
if (l->flags & LUMPF_NEEDFILESTART)
{
SetLumpAddress(l);
}
wad->Seek (l->position, SEEK_SET);
if (wad != NULL) wad->Seek (l->position, SEEK_SET);
if (l->flags & LUMPF_COMPRESSED)
{
@ -1699,12 +1713,39 @@ FWadLump FWadCollection::OpenLumpNum (int lump)
frz.Read(buffer, l->size);
return FWadLump(buffer, l->size, true);
}
else if (l->flags & LUMPF_EXTERNAL)
{
FILE * f;
if (wad != NULL) // The WadRecord in this case is just a means to store a path
{
FString name;
name.Format("%s/%s", wad->Name, l->fullname);
f = fopen(name, "rb");
}
else
{
f = fopen(l->fullname, "rb");
}
// This is an external file that cannot be kept open so we have to read
// the complete contents into a memory buffer first
if (f != NULL)
{
char * buffer = new char[l->size+1]; // the last byte is used as a reference counter
buffer[l->size] = 0;
fread(buffer, 1, l->size, f);
fclose(f);
return FWadLump(buffer, l->size, true);
}
// The file got deleted or worse. At least return something.
Printf("%s: Unable to open file\n", l->fullname);
return FWadLump("", 1, false);
}
else if (wad->MemoryData != NULL)
{
// A lump from an embedded WAD
// Handling this here creates less overhead than trying
// to do it inside the FWadLump class.
return FWadLump((char*)wad->MemoryData + l->position, l->size, false);
}
else
@ -1730,13 +1771,13 @@ FWadLump *FWadCollection::ReopenLumpNum (int lump)
WadFileRecord *wad;
FILE *f;
if ((unsigned)lump >= (unsigned)NumLumps)
if ((unsigned)lump >= (unsigned)LumpInfo.Size())
{
I_Error ("W_MapLumpNum: %u >= NumLumps",lump);
}
l = &LumpInfo[lump];
wad = Wads[l->wadnum];
wad = l->wadnum >= 0? Wads[l->wadnum] : NULL;
if (l->flags & LUMPF_NEEDFILESTART)
{
@ -1754,6 +1795,34 @@ FWadLump *FWadCollection::ReopenLumpNum (int lump)
wad->Seek(address, SEEK_SET);
return new FWadLump(buffer, l->size, true); //... but restore the file pointer afterward!
}
else if (l->flags & LUMPF_EXTERNAL)
{
FILE * f;
if (wad != NULL) // The WadRecord in this case is just a means to store a path
{
FString name;
name.Format("%s/%s", wad->Name, l->fullname);
f = fopen(name, "rb");
}
else
{
f = fopen(l->fullname, "rb");
}
// This is an external file that cannot be kept open so we have to read
// the complete contents into a memory buffer first
if (f != NULL)
{
char * buffer = new char[l->size+1]; // the last byte is used as a reference counter
buffer[l->size] = 0;
fread(buffer, 1, l->size, f);
fclose(f);
return new FWadLump(buffer, l->size, true);
}
// The file got deleted or worse. At least return something.
Printf("%s: Unable to open file\n", l->fullname);
return new FWadLump("", 1, false);
}
else if (wad->MemoryData!=NULL)
{
// A lump from an embedded WAD
@ -1782,12 +1851,13 @@ FWadLump *FWadCollection::ReopenLumpNum (int lump)
// GetFileReader
//
// Retrieves the FileReader object to access the given WAD
// Careful: This is only useful for real WAD files!
//
//==========================================================================
FileReader *FWadCollection::GetFileReader(int wadnum)
{
if ((DWORD)wadnum >= NumWads)
if ((DWORD)wadnum >= Wads.Size())
{
return NULL;
}
@ -1806,7 +1876,7 @@ const char *FWadCollection::GetWadName (int wadnum) const
{
const char *name, *slash;
if ((DWORD)wadnum >= NumWads)
if ((DWORD)wadnum >= Wads.Size())
{
return NULL;
}
@ -1826,7 +1896,7 @@ const char *FWadCollection::GetWadName (int wadnum) const
const char *FWadCollection::GetWadFullName (int wadnum) const
{
if ((unsigned int)wadnum >= NumWads)
if ((unsigned int)wadnum >= Wads.Size())
{
return NULL;
}
@ -1854,7 +1924,7 @@ bool FWadCollection::IsUncompressedFile(int lump) const
LumpRecord * l = &LumpInfo[lump];
if (l->flags & LUMPF_COMPRESSED) return false;
if (l->flags & (LUMPF_COMPRESSED|LUMPF_EXTERNAL)) return false;
else if (Wads[l->wadnum]->MemoryData!=NULL) return false;
else return true;
}
@ -1893,7 +1963,7 @@ void FWadCollection::SkinHack (int baselump)
{
bool skinned = false;
bool hasmap = false;
size_t i;
DWORD i;
for (i = baselump; i < NumLumps; i++)
{
@ -1908,7 +1978,7 @@ void FWadCollection::SkinHack (int baselump)
if (!skinned)
{
skinned = true;
size_t j;
DWORD j;
for (j = baselump; j < NumLumps; j++)
{

View file

@ -25,6 +25,7 @@
#include "files.h"
#include "doomdef.h"
#include "tarray.h"
// [RH] Compare wad header as ints instead of chars
#define IWAD_ID MAKE_ID('I','W','A','D')
@ -209,6 +210,8 @@ public:
int GetNumLumps () const;
int AddExternalFile(const char *filename);
protected:
class WadFileRecord;
struct LumpRecord;
@ -220,9 +223,9 @@ protected:
WORD *NextLumpIndex_FullName;
LumpRecord *LumpInfo;
WadFileRecord **Wads;
DWORD NumLumps;
TArray<LumpRecord> LumpInfo;
TArray<WadFileRecord *>Wads;
DWORD NumLumps; // Not necessarily the same as LumpInfo.Size()
DWORD NumWads;
void SkinHack (int baselump);

View file

@ -9433,6 +9433,10 @@
RelativePath=".\src\r_draw.h"
>
</File>
<File
RelativePath=".\src\r_jpeg.h"
>
</File>
<File
RelativePath=".\src\r_local.h"
>