- 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) 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 - Took MF2_WINDTHRUST off AMorphedMonster. This is something that should not
be a default setting. be a default setting.
- Moved a_artiegg.cpp to g_shared and renamed it to a_morph.cpp to better reflect - 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) 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->CloseOnDestruct = false;
map->lumpnum = lump_name; map->lumpnum = lump_name;

View file

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

View file

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

View file

@ -731,6 +731,7 @@ public:
void AddTiles (void *tileFile); void AddTiles (void *tileFile);
void AddExtraTextures (); // Adds patches in the ns_newtextures namespace 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 CreateTexture (int lumpnum, int usetype=FTexture::TEX_Any); // Also calls AddTexture
int AddTexture (FTexture *texture); int AddTexture (FTexture *texture);
int AddPatch (const char *patchname, int namespc=0); 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_COMPRESSED = 2, // Zip-compressed
LUMPF_ZIPFILE = 4, // Inside a Zip file - used to enforce use of special directories insize Zips 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_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 class FWadCollection::WadFileRecord : public FileReader
@ -161,7 +162,7 @@ void uppercopy (char *to, const char *from)
FWadCollection::FWadCollection () FWadCollection::FWadCollection ()
: FirstLumpIndex(NULL), NextLumpIndex(NULL), : FirstLumpIndex(NULL), NextLumpIndex(NULL),
FirstLumpIndex_FullName(NULL), NextLumpIndex_FullName(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; delete[] NextLumpIndex_FullName;
NextLumpIndex_FullName = NULL; NextLumpIndex_FullName = NULL;
} }
if (LumpInfo != NULL) for (DWORD i = 0; i < LumpInfo.Size(); ++i)
{ {
for (DWORD i = 0; i < NumLumps; ++i) if (LumpInfo[i].fullname != NULL)
{ {
if (LumpInfo[i].fullname != NULL) delete[] LumpInfo[i].fullname;
{
delete[] LumpInfo[i].fullname;
}
} }
free (LumpInfo);
LumpInfo = NULL;
} }
if (Wads != NULL) LumpInfo.Clear();
for (DWORD i = 0; i < Wads.Size(); ++i)
{ {
for (DWORD i = 0; i < NumWads; ++i) delete Wads[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 // open all the files, load headers, and count lumps
numfiles = 0; numfiles = 0;
NumWads = 0; Wads.Clear();
LumpInfo.Clear();
NumLumps = 0; NumLumps = 0;
LumpInfo = NULL; // will be realloced as lumps are added
while (*filenames) while (*filenames)
{ {
@ -276,6 +270,28 @@ void FWadCollection::InitMultipleFiles (wadlist_t **filenames)
InitHashChains (); 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) #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)); BloodCrypt (lumps, header.rff.DirOfs, header.rff.NumLumps * sizeof(rfflump_t));
NumLumps += header.rff.NumLumps; NumLumps += header.rff.NumLumps;
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); LumpInfo.Resize(NumLumps);
lump_p = &LumpInfo[startlump]; lump_p = &LumpInfo[startlump];
for (i = 0, rff_p = lumps; i < header.rff.NumLumps; ++i, ++rff_p) 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); uppercopy (lump_p->name, rff_p->Name);
lump_p->name[8] = 0; 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->position = LittleLong(rff_p->FilePos);
lump_p->size = LittleLong(rff_p->Size); lump_p->size = LittleLong(rff_p->Size);
lump_p->flags = (rff_p->Flags & 0x10) >> 4; 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); pos = sizeof(grpinfo_t) + header.grp.NumLumps * sizeof(grplump_t);
NumLumps += header.grp.NumLumps; NumLumps += header.grp.NumLumps;
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); LumpInfo.Resize(NumLumps);
lump_p = &LumpInfo[startlump]; lump_p = &LumpInfo[startlump];
for (i = 0, grp_p = lumps; i < header.grp.NumLumps; ++i, ++grp_p) 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->position = pos;
lump_p->size = LittleLong(grp_p->Size); lump_p->size = LittleLong(grp_p->Size);
pos += lump_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); NumLumps += LittleShort(info.wEntryCount);
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); LumpInfo.Resize(NumLumps);
lump_p = &LumpInfo[startlump]; lump_p = &LumpInfo[startlump];
// Load the entire central directory. Too bad that this contains variable length entries... // 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); 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? lump_p->flags = LittleShort(zip_fh->wCompression) == Z_DEFLATED?
LUMPF_COMPRESSED|LUMPF_ZIPFILE : LUMPF_ZIPFILE; LUMPF_COMPRESSED|LUMPF_ZIPFILE : LUMPF_ZIPFILE;
lump_p->compressedsize = LittleLong(zip_fh->dwCompressedSize); 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 // Resize the lump record array to its actual size
NumLumps -= skipped; NumLumps -= skipped;
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); LumpInfo.Resize(NumLumps);
// Entries in Zips are sorted alphabetically. // Entries in Zips are sorted alphabetically.
qsort(LumpInfo + startlump, NumLumps - startlump, sizeof(LumpRecord), lumpcmp); qsort(&LumpInfo[startlump], NumLumps - startlump, sizeof(LumpRecord), lumpcmp);
} }
else else
{ // This is just a single lump file { // 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] != ZIP_ID &&
(header.magic[0] != GRP_ID_0 || header.magic[1] != GRP_ID_1 || header.magic[2] != GRP_ID_2)) (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]; lump_p = &LumpInfo[startlump];
for (i = startlump; i < (unsigned)NumLumps; i++, lump_p++, fileinfo++) for (i = startlump; i < (unsigned)NumLumps; i++, lump_p++, fileinfo++)
{ {
// [RH] Convert name to uppercase during copy // [RH] Convert name to uppercase during copy
uppercopy (lump_p->name, fileinfo->Name); uppercopy (lump_p->name, fileinfo->Name);
lump_p->name[8] = 0; lump_p->name[8] = 0;
lump_p->wadnum = (WORD)NumWads; lump_p->wadnum = (WORD)Wads.Size();
lump_p->position = LittleLong(fileinfo->FilePos); lump_p->position = LittleLong(fileinfo->FilePos);
lump_p->size = LittleLong(fileinfo->Size); lump_p->size = LittleLong(fileinfo->Size);
lump_p->namespc = ns_global; lump_p->namespc = ns_global;
@ -690,11 +706,10 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
wadinfo->FirstLump = startlump; wadinfo->FirstLump = startlump;
wadinfo->LastLump = NumLumps - 1; wadinfo->LastLump = NumLumps - 1;
Wads = (WadFileRecord **)M_Realloc (Wads, (++NumWads)*sizeof(WadFileRecord*)); Wads.Push(wadinfo);
Wads[NumWads-1] = wadinfo;
// [RH] Put the Strife Teaser voices into the voices namespace // [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 (); FindStrifeTeaserVoices ();
} }
@ -759,7 +774,7 @@ int FWadCollection::CheckIfWadLoaded (const char *name)
if (strrchr (name, '/') != NULL) if (strrchr (name, '/') != NULL)
{ {
for (i = 0; i < NumWads; ++i) for (i = 0; i < Wads.Size(); ++i)
{ {
if (stricmp (GetWadFullName (i), name) == 0) if (stricmp (GetWadFullName (i), name) == 0)
{ {
@ -769,7 +784,7 @@ int FWadCollection::CheckIfWadLoaded (const char *name)
} }
else else
{ {
for (i = 0; i < NumWads; ++i) for (i = 0; i < Wads.Size(); ++i)
{ {
if (stricmp (GetWadName (i), name) == 0) 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 // If the previous lump was of the form FF_END and this one is
// of the form F_END, ignore this as a marker // 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 && if ((lump - 1)->name[0] == *marker &&
strncmp ((lump - 1)->name + 1, marker, 7) == 0) strncmp ((lump - 1)->name + 1, marker, 7) == 0)
@ -1204,7 +1219,7 @@ void FWadCollection::ScanForFlatHack (int startlump)
} }
} }
++NumLumps; ++NumLumps;
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, NumLumps*sizeof(LumpRecord)); LumpInfo.Resize(NumLumps);
for (; i > j; --i) for (; i > j; --i)
{ {
LumpInfo[i+1] = LumpInfo[i]; LumpInfo[i+1] = LumpInfo[i];
@ -1384,7 +1399,7 @@ int FWadCollection::MergeLumps (const char *start, const char *end, int space)
} }
else else
// Check if this is the start of a block // Check if this is the start of a block
if (IsMarker (LumpInfo + i, ustart)) if (IsMarker (&LumpInfo[i], ustart))
{ {
insideBlock = true; insideBlock = true;
markerpos = i; markerpos = i;
@ -1415,7 +1430,7 @@ int FWadCollection::MergeLumps (const char *start, const char *end, int space)
insideBlock = false; insideBlock = false;
LumpInfo[oldlumps++] = LumpInfo[i]; 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 // It is the end of a block. We'll add the end marker once
// we've processed everything. // we've processed everything.
@ -1434,10 +1449,9 @@ int FWadCollection::MergeLumps (const char *start, const char *end, int space)
if (newlumps) if (newlumps)
{ {
if (size_t(oldlumps + newlumps) >= NumLumps) LumpInfo.Resize(oldlumps+newlumps+1);
LumpInfo = (LumpRecord *)M_Realloc (LumpInfo, (oldlumps + newlumps + 1) * sizeof(LumpRecord) );
memcpy (LumpInfo + oldlumps, newlumpinfos, sizeof(LumpRecord) * newlumps); memcpy (&LumpInfo[oldlumps], newlumpinfos, sizeof(LumpRecord) * newlumps);
markerpos = oldlumps; markerpos = oldlumps;
NumLumps = oldlumps + newlumps; NumLumps = oldlumps + newlumps;
@ -1502,13 +1516,13 @@ int FWadCollection::FindLump (const char *name, int *lastlump, bool anyns)
uppercopy (name8, name); uppercopy (name8, name);
lump_p = LumpInfo + *lastlump; lump_p = &LumpInfo[*lastlump];
while (lump_p < LumpInfo + NumLumps) while (lump_p < &LumpInfo[NumLumps])
{ {
if ((anyns || lump_p->namespc == ns_global) && if ((anyns || lump_p->namespc == ns_global) &&
*(__int64 *)&lump_p->name == *(__int64 *)&name8) *(__int64 *)&lump_p->name == *(__int64 *)&name8)
{ {
int lump = lump_p - LumpInfo; int lump = lump_p - &LumpInfo[0];
*lastlump = lump + 1; *lastlump = lump + 1;
return lump; return lump;
} }
@ -1587,7 +1601,7 @@ int FWadCollection::GetLumpNamespace (int lump) const
int FWadCollection::GetLumpFile (int lump) const int FWadCollection::GetLumpFile (int lump) const
{ {
if ((size_t)lump >= NumLumps) if ((size_t)lump >= LumpInfo.Size())
return -1; return -1;
return LumpInfo[lump].wadnum; return LumpInfo[lump].wadnum;
} }
@ -1675,20 +1689,20 @@ FWadLump FWadCollection::OpenLumpNum (int lump)
LumpRecord *l; LumpRecord *l;
WadFileRecord *wad; WadFileRecord *wad;
if ((unsigned)lump >= (unsigned)NumLumps) if ((unsigned)lump >= (unsigned)LumpInfo.Size())
{ {
I_Error ("W_MapLumpNum: %u >= NumLumps",lump); I_Error ("W_MapLumpNum: %u >= NumLumps",lump);
} }
l = &LumpInfo[lump]; l = &LumpInfo[lump];
wad = Wads[l->wadnum]; wad = l->wadnum >= 0? Wads[l->wadnum] : NULL;
if (l->flags & LUMPF_NEEDFILESTART) if (l->flags & LUMPF_NEEDFILESTART)
{ {
SetLumpAddress(l); SetLumpAddress(l);
} }
wad->Seek (l->position, SEEK_SET); if (wad != NULL) wad->Seek (l->position, SEEK_SET);
if (l->flags & LUMPF_COMPRESSED) if (l->flags & LUMPF_COMPRESSED)
{ {
@ -1699,12 +1713,39 @@ FWadLump FWadCollection::OpenLumpNum (int lump)
frz.Read(buffer, l->size); frz.Read(buffer, l->size);
return FWadLump(buffer, l->size, true); 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) else if (wad->MemoryData != NULL)
{ {
// A lump from an embedded WAD // A lump from an embedded WAD
// Handling this here creates less overhead than trying // Handling this here creates less overhead than trying
// to do it inside the FWadLump class. // to do it inside the FWadLump class.
return FWadLump((char*)wad->MemoryData + l->position, l->size, false); return FWadLump((char*)wad->MemoryData + l->position, l->size, false);
} }
else else
@ -1730,13 +1771,13 @@ FWadLump *FWadCollection::ReopenLumpNum (int lump)
WadFileRecord *wad; WadFileRecord *wad;
FILE *f; FILE *f;
if ((unsigned)lump >= (unsigned)NumLumps) if ((unsigned)lump >= (unsigned)LumpInfo.Size())
{ {
I_Error ("W_MapLumpNum: %u >= NumLumps",lump); I_Error ("W_MapLumpNum: %u >= NumLumps",lump);
} }
l = &LumpInfo[lump]; l = &LumpInfo[lump];
wad = Wads[l->wadnum]; wad = l->wadnum >= 0? Wads[l->wadnum] : NULL;
if (l->flags & LUMPF_NEEDFILESTART) if (l->flags & LUMPF_NEEDFILESTART)
{ {
@ -1754,6 +1795,34 @@ FWadLump *FWadCollection::ReopenLumpNum (int lump)
wad->Seek(address, SEEK_SET); wad->Seek(address, SEEK_SET);
return new FWadLump(buffer, l->size, true); //... but restore the file pointer afterward! 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) else if (wad->MemoryData!=NULL)
{ {
// A lump from an embedded WAD // A lump from an embedded WAD
@ -1782,12 +1851,13 @@ FWadLump *FWadCollection::ReopenLumpNum (int lump)
// GetFileReader // GetFileReader
// //
// Retrieves the FileReader object to access the given WAD // Retrieves the FileReader object to access the given WAD
// Careful: This is only useful for real WAD files!
// //
//========================================================================== //==========================================================================
FileReader *FWadCollection::GetFileReader(int wadnum) FileReader *FWadCollection::GetFileReader(int wadnum)
{ {
if ((DWORD)wadnum >= NumWads) if ((DWORD)wadnum >= Wads.Size())
{ {
return NULL; return NULL;
} }
@ -1806,7 +1876,7 @@ const char *FWadCollection::GetWadName (int wadnum) const
{ {
const char *name, *slash; const char *name, *slash;
if ((DWORD)wadnum >= NumWads) if ((DWORD)wadnum >= Wads.Size())
{ {
return NULL; return NULL;
} }
@ -1826,7 +1896,7 @@ const char *FWadCollection::GetWadName (int wadnum) const
const char *FWadCollection::GetWadFullName (int wadnum) const const char *FWadCollection::GetWadFullName (int wadnum) const
{ {
if ((unsigned int)wadnum >= NumWads) if ((unsigned int)wadnum >= Wads.Size())
{ {
return NULL; return NULL;
} }
@ -1854,7 +1924,7 @@ bool FWadCollection::IsUncompressedFile(int lump) const
LumpRecord * l = &LumpInfo[lump]; 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 if (Wads[l->wadnum]->MemoryData!=NULL) return false;
else return true; else return true;
} }
@ -1893,7 +1963,7 @@ void FWadCollection::SkinHack (int baselump)
{ {
bool skinned = false; bool skinned = false;
bool hasmap = false; bool hasmap = false;
size_t i; DWORD i;
for (i = baselump; i < NumLumps; i++) for (i = baselump; i < NumLumps; i++)
{ {
@ -1908,7 +1978,7 @@ void FWadCollection::SkinHack (int baselump)
if (!skinned) if (!skinned)
{ {
skinned = true; skinned = true;
size_t j; DWORD j;
for (j = baselump; j < NumLumps; j++) for (j = baselump; j < NumLumps; j++)
{ {

View file

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

View file

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