mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- complete restructuring of resource file handling for more flexibility and future
extensions. - Removed merging of special namespaces. For the texture manager this has become totally useless so there is no need to do this anymore. Not merging the namespaces also allows a much more reliable detection of lumps belonging to special namespaces so the ScanForFlatHack function is no longer needed. Instead, any lump up to F_END with a length of 4096 will be marked for inclusion as a flat texture if no F_START marker is found. - Made the counting of intermission stats in Doom a GAMEINFO option so that it can be activated in all games. SVN r1555 (trunk)
This commit is contained in:
parent
a2a69765eb
commit
cc066bc409
27 changed files with 2868 additions and 2143 deletions
|
@ -1,4 +1,21 @@
|
|||
April 17, 2009
|
||||
April 23, 2009 (Changes by Graf Zahl)
|
||||
- complete restructuring of resource file handling for more flexibility and future
|
||||
extensions.
|
||||
- Removed merging of special namespaces. For the texture manager this has
|
||||
become totally useless so there is no need to do this anymore. Not merging
|
||||
the namespaces also allows a much more reliable detection of lumps belonging
|
||||
to special namespaces so the ScanForFlatHack function is no longer needed.
|
||||
Instead, any lump up to F_END with a length of 4096 will be marked for
|
||||
inclusion as a flat texture if no F_START marker is found.
|
||||
|
||||
April 21, 2009 (Changes by Graf Zahl)
|
||||
- fixed MustConfirm parsing in MAPINFO
|
||||
|
||||
April 19, 2009 (Changes by Graf Zahl)
|
||||
- Made the counting of intermission stats in Doom a GAMEINFO option so that
|
||||
it can be activated in all games.
|
||||
|
||||
April 17, 2009
|
||||
- Gave the intermission screen sounds their own SNDINFO entries.
|
||||
|
||||
April 16, 2009
|
||||
|
|
|
@ -656,6 +656,14 @@ add_executable( zdoom WIN32
|
|||
oplsynth/music_opldumper_mididevice.cpp
|
||||
oplsynth/music_opl_mididevice.cpp
|
||||
oplsynth/opl_mus_player.cpp
|
||||
resourcefiles/file_7z.cpp
|
||||
resourcefiles/file_grp.cpp
|
||||
resourcefiles/file_lump.cpp
|
||||
resourcefiles/file_rff.cpp
|
||||
resourcefiles/file_wad.cpp
|
||||
resourcefiles/file.zip.cpp
|
||||
resourcefiles/file_pak.cpp
|
||||
resourcefiles/resourcefile.cpp
|
||||
sfmt/SFMT.cpp
|
||||
sound/fmodsound.cpp
|
||||
sound/i_music.cpp
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
void ResetFilePtr ();
|
||||
|
||||
FILE *GetFile () const { return File; }
|
||||
virtual const char *GetBuffer() const { return NULL; }
|
||||
|
||||
FileReader &operator>> (BYTE &v)
|
||||
{
|
||||
|
@ -279,6 +280,7 @@ public:
|
|||
virtual long Seek (long offset, int origin);
|
||||
virtual long Read (void *buffer, long len);
|
||||
virtual char *Gets(char *strbuf, int len);
|
||||
virtual const char *GetBuffer() const { return bufptr; }
|
||||
|
||||
protected:
|
||||
const char * bufptr;
|
||||
|
|
|
@ -260,6 +260,7 @@ void FMapInfoParser::ParseGameInfo()
|
|||
GAMEINFOKEY_STRING(intermissionMusic, "intermissionMusic")
|
||||
GAMEINFOKEY_BOOL(noloopfinalemusic, "noloopfinalemusic")
|
||||
GAMEINFOKEY_BOOL(drawreadthis, "drawreadthis")
|
||||
GAMEINFOKEY_BOOL(intermissioncounter, "intermissioncounter")
|
||||
else
|
||||
{
|
||||
// ignore unkown keys.
|
||||
|
|
1
src/gi.h
1
src/gi.h
|
@ -69,6 +69,7 @@ struct gameinfo_t
|
|||
char titlePage[9];
|
||||
bool drawreadthis;
|
||||
bool noloopfinalemusic;
|
||||
bool intermissioncounter;
|
||||
TArray<FName> creditPages;
|
||||
TArray<FName> finalePages;
|
||||
TArray<FName> infoPages;
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
|
||||
void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt);
|
||||
void P_SetSlopes ();
|
||||
void BloodCrypt (void *data, int key, int len);
|
||||
|
||||
extern AActor *P_SpawnMapThing (FMapThing *mthing, int position);
|
||||
extern bool P_LoadBuildMap (BYTE *mapdata, size_t len, FMapThing **things, int *numthings);
|
||||
|
|
128
src/r_data.cpp
128
src/r_data.cpp
|
@ -48,22 +48,22 @@
|
|||
#include "v_palette.h"
|
||||
|
||||
|
||||
static int R_CountGroup (const char *start, const char *end);
|
||||
static int R_CountTexturesX ();
|
||||
static int R_CountLumpTextures (int lumpnum);
|
||||
|
||||
extern void R_DeinitBuildTiles();
|
||||
extern int R_CountBuildTiles();
|
||||
|
||||
static struct FakeCmap
|
||||
struct FakeCmap
|
||||
{
|
||||
char name[8];
|
||||
PalEntry blend;
|
||||
} *fakecmaps;
|
||||
int lump;
|
||||
};
|
||||
|
||||
size_t numfakecmaps;
|
||||
int firstfakecmap;
|
||||
TArray<FakeCmap> fakecmaps;
|
||||
BYTE *realcolormaps;
|
||||
size_t numfakecmaps;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -138,24 +138,39 @@ void R_InitColormaps ()
|
|||
// [RH] Try and convert BOOM colormaps into blending values.
|
||||
// This is a really rough hack, but it's better than
|
||||
// not doing anything with them at all (right?)
|
||||
int lastfakecmap = Wads.CheckNumForName ("C_END");
|
||||
firstfakecmap = Wads.CheckNumForName ("C_START");
|
||||
|
||||
if (firstfakecmap == -1 || lastfakecmap == -1)
|
||||
numfakecmaps = 1;
|
||||
else
|
||||
numfakecmaps = lastfakecmap - firstfakecmap;
|
||||
realcolormaps = new BYTE[256*NUMCOLORMAPS*numfakecmaps];
|
||||
fakecmaps = new FakeCmap[numfakecmaps];
|
||||
FakeCmap cm;
|
||||
|
||||
fakecmaps[0].name[0] = 0;
|
||||
cm.name[0] = 0;
|
||||
cm.blend = 0;
|
||||
fakecmaps.Push(cm);
|
||||
|
||||
DWORD NumLumps = Wads.GetNumLumps();
|
||||
|
||||
for (DWORD i = 0; i < NumLumps; i++)
|
||||
{
|
||||
if (Wads.GetLumpNamespace(i) == ns_colormaps)
|
||||
{
|
||||
char name[9];
|
||||
name[8] = 0;
|
||||
Wads.GetLumpName (name, ns_colormaps);
|
||||
|
||||
if (Wads.CheckNumForName (name, ns_colormaps) == i)
|
||||
{
|
||||
strncpy(cm.name, name, 8);
|
||||
cm.blend = 0;
|
||||
fakecmaps.Push(cm);
|
||||
}
|
||||
}
|
||||
}
|
||||
realcolormaps = new BYTE[256*NUMCOLORMAPS*fakecmaps.Size()];
|
||||
R_SetDefaultColormap ("COLORMAP");
|
||||
|
||||
if (numfakecmaps > 1)
|
||||
if (fakecmaps.Size() > 1)
|
||||
{
|
||||
BYTE unremap[256], remap[256], mapin[256];
|
||||
int i;
|
||||
size_t j;
|
||||
unsigned j;
|
||||
|
||||
memcpy (remap, GPalette.Remap, 256);
|
||||
memset (unremap, 0, 256);
|
||||
|
@ -164,12 +179,12 @@ void R_InitColormaps ()
|
|||
unremap[remap[i]] = i;
|
||||
}
|
||||
remap[0] = 0;
|
||||
for (i = ++firstfakecmap, j = 1; j < numfakecmaps; i++, j++)
|
||||
for (j = 1; j < fakecmaps.Size(); j++)
|
||||
{
|
||||
if (Wads.LumpLength (i) >= (NUMCOLORMAPS+1)*256)
|
||||
if (Wads.LumpLength (fakecmaps[j].lump) >= (NUMCOLORMAPS+1)*256)
|
||||
{
|
||||
int k, r, g, b;
|
||||
FWadLump lump = Wads.OpenLumpNum (i);
|
||||
FWadLump lump = Wads.OpenLumpNum (fakecmaps[j].lump);
|
||||
BYTE *const map = realcolormaps + NUMCOLORMAPS*256*j;
|
||||
|
||||
for (k = 0; k < NUMCOLORMAPS; ++k)
|
||||
|
@ -191,12 +206,12 @@ void R_InitColormaps ()
|
|||
g += GPalette.BaseColors[map[k]].g;
|
||||
b += GPalette.BaseColors[map[k]].b;
|
||||
}
|
||||
Wads.GetLumpName (fakecmaps[j].name, i);
|
||||
fakecmaps[j].blend = PalEntry (255, r/256, g/256, b/256);
|
||||
}
|
||||
}
|
||||
}
|
||||
NormalLight.Maps = realcolormaps;
|
||||
numfakecmaps = fakecmaps.Size();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -207,11 +222,6 @@ void R_InitColormaps ()
|
|||
|
||||
void R_DeinitColormaps ()
|
||||
{
|
||||
if (fakecmaps != NULL)
|
||||
{
|
||||
delete[] fakecmaps;
|
||||
fakecmaps = NULL;
|
||||
}
|
||||
if (realcolormaps != NULL)
|
||||
{
|
||||
delete[] realcolormaps;
|
||||
|
@ -229,18 +239,20 @@ void R_DeinitColormaps ()
|
|||
|
||||
DWORD R_ColormapNumForName (const char *name)
|
||||
{
|
||||
int lump;
|
||||
DWORD blend = 0;
|
||||
|
||||
if (strnicmp (name, "COLORMAP", 8))
|
||||
{ // COLORMAP always returns 0
|
||||
if (-1 != (lump = Wads.CheckNumForName (name, ns_colormaps)) )
|
||||
blend = lump - firstfakecmap + 1;
|
||||
else if (!strnicmp (name, "WATERMAP", 8))
|
||||
blend = MAKEARGB (128,0,0x4f,0xa5);
|
||||
for(int i=fakecmaps.Size()-1; i > 0; i++)
|
||||
{
|
||||
if (!strnicmp(name, fakecmaps[i].name, 8))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return blend;
|
||||
if (!strnicmp (name, "WATERMAP", 8))
|
||||
return MAKEARGB (128,0,0x4f,0xa5);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -252,7 +264,7 @@ DWORD R_ColormapNumForName (const char *name)
|
|||
DWORD R_BlendForColormap (DWORD map)
|
||||
{
|
||||
return APART(map) ? map :
|
||||
map < numfakecmaps ? DWORD(fakecmaps[map].blend) : 0;
|
||||
map < fakecmaps.Size() ? DWORD(fakecmaps[map].blend) : 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -284,38 +296,34 @@ void R_InitData ()
|
|||
|
||||
int R_GuesstimateNumTextures ()
|
||||
{
|
||||
int numtex;
|
||||
int numtex = 0;
|
||||
|
||||
for(int i = Wads.GetNumLumps()-1; i>=0; i--)
|
||||
{
|
||||
int space = Wads.GetLumpNamespace(i);
|
||||
switch(space)
|
||||
{
|
||||
case ns_flats:
|
||||
case ns_sprites:
|
||||
case ns_newtextures:
|
||||
case ns_hires:
|
||||
case ns_patches:
|
||||
case ns_graphics:
|
||||
numtex++;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Wads.GetLumpFlags(i) & LUMPF_MAYBEFLAT) numtex++;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
numtex = R_CountGroup ("S_START", "S_END");
|
||||
numtex += R_CountGroup ("F_START", "F_END");
|
||||
numtex += R_CountGroup ("TX_START", "TX_END");
|
||||
numtex += R_CountGroup ("HI_START", "HI_END");
|
||||
numtex += R_CountBuildTiles ();
|
||||
numtex += R_CountTexturesX ();
|
||||
return numtex;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// R_CountGroup
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
static int R_CountGroup (const char *start, const char *end)
|
||||
{
|
||||
int startl = Wads.CheckNumForName (start);
|
||||
int endl = Wads.CheckNumForName (end);
|
||||
|
||||
if (startl < 0 || endl < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return endl - startl - 1;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// R_CountTexturesX
|
||||
|
|
350
src/resourcefiles/file_7z.cpp
Normal file
350
src/resourcefiles/file_7z.cpp
Normal file
|
@ -0,0 +1,350 @@
|
|||
/*
|
||||
** file_7z.cpp
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2009 Randy Heit
|
||||
** Copyright 2009 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
#include "resourcefile.h"
|
||||
#include "cmdlib.h"
|
||||
#include "templates.h"
|
||||
#include "v_text.h"
|
||||
#include "w_zip.h"
|
||||
#include "i_system.h"
|
||||
#include "w_wad.h"
|
||||
|
||||
extern "C" {
|
||||
#include "Archive/7z/7zHeader.h"
|
||||
#include "Archive/7z/7zExtract.h"
|
||||
#include "Archive/7z/7zIn.h"
|
||||
#include "7zCrc.h"
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
//
|
||||
// Interface classes to 7z library
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
extern ISzAlloc g_Alloc;
|
||||
|
||||
struct CZDFileInStream
|
||||
{
|
||||
ISeekInStream s;
|
||||
FileReader *File;
|
||||
|
||||
CZDFileInStream(FileReader *_file)
|
||||
{
|
||||
s.Read = Read;
|
||||
s.Seek = Seek;
|
||||
File = _file;
|
||||
}
|
||||
|
||||
static SRes Read(void *pp, void *buf, size_t *size)
|
||||
{
|
||||
CZDFileInStream *p = (CZDFileInStream *)pp;
|
||||
long numread = p->File->Read(buf, (long)*size);
|
||||
if (numread < 0)
|
||||
{
|
||||
*size = 0;
|
||||
return SZ_ERROR_READ;
|
||||
}
|
||||
*size = numread;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static SRes Seek(void *pp, Int64 *pos, ESzSeek origin)
|
||||
{
|
||||
CZDFileInStream *p = (CZDFileInStream *)pp;
|
||||
int move_method;
|
||||
int res;
|
||||
if (origin == SZ_SEEK_SET)
|
||||
{
|
||||
move_method = SEEK_SET;
|
||||
}
|
||||
else if (origin == SZ_SEEK_CUR)
|
||||
{
|
||||
move_method = SEEK_CUR;
|
||||
}
|
||||
else if (origin == SZ_SEEK_END)
|
||||
{
|
||||
move_method = SEEK_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
res = p->File->Seek((long)*pos, move_method);
|
||||
*pos = p->File->Tell();
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
struct C7zArchive
|
||||
{
|
||||
CSzArEx DB;
|
||||
CZDFileInStream ArchiveStream;
|
||||
CLookToRead LookStream;
|
||||
UInt32 BlockIndex;
|
||||
Byte *OutBuffer;
|
||||
size_t OutBufferSize;
|
||||
|
||||
C7zArchive(FileReader *file) : ArchiveStream(file)
|
||||
{
|
||||
if (g_CrcTable[1] == 0)
|
||||
{
|
||||
CrcGenerateTable();
|
||||
}
|
||||
file->Seek(0, SEEK_SET);
|
||||
LookToRead_CreateVTable(&LookStream, false);
|
||||
LookStream.realStream = &ArchiveStream.s;
|
||||
LookToRead_Init(&LookStream);
|
||||
SzArEx_Init(&DB);
|
||||
BlockIndex = 0xFFFFFFFF;
|
||||
OutBuffer = NULL;
|
||||
OutBufferSize = 0;
|
||||
}
|
||||
|
||||
~C7zArchive()
|
||||
{
|
||||
if (OutBuffer != NULL)
|
||||
{
|
||||
IAlloc_Free(&g_Alloc, OutBuffer);
|
||||
}
|
||||
SzArEx_Free(&DB, &g_Alloc);
|
||||
}
|
||||
|
||||
SRes Open()
|
||||
{
|
||||
return SzArEx_Open(&DB, &LookStream.s, &g_Alloc, &g_Alloc);
|
||||
}
|
||||
|
||||
SRes Extract(UInt32 file_index, char *buffer)
|
||||
{
|
||||
size_t offset, out_size_processed;
|
||||
SRes res = SzAr_Extract(&DB, &LookStream.s, file_index,
|
||||
&BlockIndex, &OutBuffer, &OutBufferSize,
|
||||
&offset, &out_size_processed,
|
||||
&g_Alloc, &g_Alloc);
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
memcpy(buffer, OutBuffer + offset, out_size_processed);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
//==========================================================================
|
||||
//
|
||||
// Zip Lump
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
struct F7ZLump : public FResourceLump
|
||||
{
|
||||
int Position;
|
||||
|
||||
virtual int FillCache();
|
||||
|
||||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Zip file
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class F7ZFile : public FResourceFile
|
||||
{
|
||||
friend struct F7ZLump;
|
||||
|
||||
F7ZLump *Lumps;
|
||||
C7zArchive *Archive;
|
||||
|
||||
static int STACK_ARGS lumpcmp(const void * a, const void * b);
|
||||
|
||||
public:
|
||||
F7ZFile(const char * filename, FileReader *filer);
|
||||
bool Open();
|
||||
virtual ~F7ZFile();
|
||||
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
int STACK_ARGS F7ZFile::lumpcmp(const void * a, const void * b)
|
||||
{
|
||||
F7ZLump * rec1 = (F7ZLump *)a;
|
||||
F7ZLump * rec2 = (F7ZLump *)b;
|
||||
|
||||
return stricmp(rec1->FullName, rec2->FullName);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// 7Z file
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
F7ZFile::F7ZFile(const char * filename, FileReader *filer)
|
||||
: FResourceFile(filename, filer)
|
||||
{
|
||||
Lumps = NULL;
|
||||
Archive = NULL;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Open it
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool F7ZFile::Open()
|
||||
{
|
||||
Archive = new C7zArchive(Reader);
|
||||
int skipped = 0;
|
||||
SRes res;
|
||||
|
||||
res = Archive->Open();
|
||||
if (res != SZ_OK)
|
||||
{
|
||||
delete Archive;
|
||||
Archive = NULL;
|
||||
Printf("\n"TEXTCOLOR_RED"%s: ", Filename);
|
||||
if (res == SZ_ERROR_UNSUPPORTED)
|
||||
{
|
||||
Printf("Decoder does not support this archive\n");
|
||||
}
|
||||
else if (res == SZ_ERROR_MEM)
|
||||
{
|
||||
Printf("Cannot allocate memory\n");
|
||||
}
|
||||
else if (res == SZ_ERROR_CRC)
|
||||
{
|
||||
Printf("CRC error\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("error #%d\n", res);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
NumLumps = Archive->DB.db.NumFiles;
|
||||
|
||||
Lumps = new F7ZLump[NumLumps];
|
||||
|
||||
F7ZLump *lump_p = Lumps;
|
||||
for (int i = 0; i < NumLumps; ++i)
|
||||
{
|
||||
CSzFileItem *file = &Archive->DB.db.Files[i];
|
||||
char name[256];
|
||||
|
||||
// skip Directories
|
||||
if (file->IsDir)
|
||||
{
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
strncpy(name, file->Name, countof(name)-1);
|
||||
name[countof(name)-1] = 0;
|
||||
FixPathSeperator(name);
|
||||
strlwr(name);
|
||||
|
||||
lump_p->LumpNameSetup(name);
|
||||
lump_p->LumpSize = file->Size;
|
||||
lump_p->Owner = this;
|
||||
lump_p->Flags = LUMPF_ZIPFILE;
|
||||
lump_p->Position = i;
|
||||
lump_p->CheckEmbedded();
|
||||
lump_p++;
|
||||
}
|
||||
// Resize the lump record array to its actual size
|
||||
NumLumps -= skipped;
|
||||
Printf(", %d lumps\n", NumLumps);
|
||||
|
||||
// Entries in archives are sorted alphabetically
|
||||
qsort(&Lumps[0], NumLumps, sizeof(F7ZLump), lumpcmp);
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
F7ZFile::~F7ZFile()
|
||||
{
|
||||
if (Lumps != NULL) delete [] Lumps;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Fills the lump cache and performs decompression
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int F7ZLump::FillCache()
|
||||
{
|
||||
Cache = new char[LumpSize];
|
||||
static_cast<F7ZFile*>(Owner)->Archive->Extract(Position, Cache);
|
||||
RefCount = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// File open
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FResourceFile *Check7Z(const char *filename, FileReader *file)
|
||||
{
|
||||
char head[k7zSignatureSize];
|
||||
|
||||
file->Seek(0, SEEK_SET);
|
||||
file->Read(&head, k7zSignatureSize);
|
||||
file->Seek(0, SEEK_SET);
|
||||
if (!memcmp(head, k7zSignature, k7zSignatureSize))
|
||||
{
|
||||
FResourceFile *rf = new F7ZFile(filename, file);
|
||||
if (rf->Open()) return rf;
|
||||
delete rf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
152
src/resourcefiles/file_grp.cpp
Normal file
152
src/resourcefiles/file_grp.cpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
** file_grp.cpp
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2009 Randy Heit
|
||||
** Copyright 2005-2009 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
#include "resourcefile.h"
|
||||
#include "cmdlib.h"
|
||||
#include "v_text.h"
|
||||
#include "w_wad.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
struct GrpInfo
|
||||
{
|
||||
DWORD Magic[3];
|
||||
DWORD NumLumps;
|
||||
};
|
||||
|
||||
struct GrpLump
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
char Name[12];
|
||||
DWORD Size;
|
||||
};
|
||||
char NameWithZero[13];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Build GRP file
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FGrpFile : public FUncompressedFile
|
||||
{
|
||||
public:
|
||||
FGrpFile(const char * filename, FileReader *file);
|
||||
bool Open();
|
||||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Initializes a Build GRP file
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FGrpFile::FGrpFile(const char *filename, FileReader *file)
|
||||
: FUncompressedFile(filename, file)
|
||||
{
|
||||
Lumps = NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Open it
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FGrpFile::Open()
|
||||
{
|
||||
GrpInfo header;
|
||||
|
||||
Reader->Read(&header, sizeof(header));
|
||||
NumLumps = LittleLong(header.NumLumps);
|
||||
|
||||
GrpLump *fileinfo = new GrpLump[NumLumps];
|
||||
Reader->Read (fileinfo, NumLumps * sizeof(GrpLump));
|
||||
|
||||
Lumps = new FUncompressedLump[NumLumps];
|
||||
|
||||
int Position = sizeof(GrpInfo) + NumLumps * sizeof(GrpLump);
|
||||
|
||||
for(DWORD i = 0; i < NumLumps; i++)
|
||||
{
|
||||
Lumps[i].Owner = this;
|
||||
Lumps[i].Position = Position;
|
||||
Lumps[i].LumpSize = LittleLong(fileinfo[i].Size);
|
||||
Position += fileinfo[i].Size;
|
||||
Lumps[i].Namespace = ns_global;
|
||||
Lumps[i].Flags = 0;
|
||||
fileinfo[i].NameWithZero[12] = '\0'; // Be sure filename is null-terminated
|
||||
Lumps[i].LumpNameSetup(fileinfo[i].NameWithZero);
|
||||
}
|
||||
Printf(", %d lumps\n", NumLumps);
|
||||
|
||||
delete[] fileinfo;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// File open
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FResourceFile *CheckGRP(const char *filename, FileReader *file)
|
||||
{
|
||||
char head[12];
|
||||
|
||||
file->Seek(0, SEEK_SET);
|
||||
file->Read(&head, 12);
|
||||
file->Seek(0, SEEK_SET);
|
||||
if (!memcmp(head, "KenSilverman", 12))
|
||||
{
|
||||
FResourceFile *rf = new FGrpFile(filename, file);
|
||||
if (rf->Open()) return rf;
|
||||
delete rf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
100
src/resourcefiles/file_lump.cpp
Normal file
100
src/resourcefiles/file_lump.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
** file_lump.cpp
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2009 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
#include "resourcefile.h"
|
||||
#include "cmdlib.h"
|
||||
#include "v_text.h"
|
||||
#include "w_wad.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Single lump
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FLumpFile : public FUncompressedFile
|
||||
{
|
||||
public:
|
||||
FLumpFile(const char * filename, FileReader *file);
|
||||
bool Open();
|
||||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FLumpFile::FLumpFile
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FLumpFile::FLumpFile(const char *filename, FileReader *file) : FUncompressedFile(filename, file)
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Open it
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FLumpFile::Open()
|
||||
{
|
||||
FString name(ExtractFileBase (Filename));
|
||||
|
||||
Lumps = new FUncompressedLump[1]; // must use array allocator
|
||||
uppercopy(Lumps->Name, name);
|
||||
Lumps->Name[8] = 0;
|
||||
Lumps->Owner = this;
|
||||
Lumps->Position = 0;
|
||||
Lumps->LumpSize = Reader->GetLength();
|
||||
Lumps->Namespace = ns_global;
|
||||
Lumps->Flags = 0;
|
||||
Lumps->FullName = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// File open
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FResourceFile *CheckLump(const char *filename, FileReader *file)
|
||||
{
|
||||
// always succeeds
|
||||
FResourceFile *rf = new FLumpFile(filename, file);
|
||||
if (rf->Open()) return rf;
|
||||
delete rf;
|
||||
return NULL;
|
||||
}
|
||||
|
1
src/resourcefiles/file_pak.cpp
Normal file
1
src/resourcefiles/file_pak.cpp
Normal file
|
@ -0,0 +1 @@
|
|||
// not implemented yet
|
251
src/resourcefiles/file_rff.cpp
Normal file
251
src/resourcefiles/file_rff.cpp
Normal file
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
** file_rff.cpp
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2009 Randy Heit
|
||||
** Copyright 2005-2009 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
#include "resourcefile.h"
|
||||
#include "cmdlib.h"
|
||||
#include "templates.h"
|
||||
#include "v_text.h"
|
||||
#include "w_wad.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
struct RFFInfo
|
||||
{
|
||||
// Should be "RFF\x18"
|
||||
DWORD Magic;
|
||||
DWORD Version;
|
||||
DWORD DirOfs;
|
||||
DWORD NumLumps;
|
||||
};
|
||||
|
||||
struct RFFLump
|
||||
{
|
||||
BYTE IDontKnow[16];
|
||||
DWORD FilePos;
|
||||
DWORD Size;
|
||||
BYTE IStillDontKnow[8];
|
||||
BYTE Flags;
|
||||
char Extension[3];
|
||||
char Name[8+4]; // 4 bytes that I don't know what they are for
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Blood RFF lump (uncompressed lump with encryption)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
struct FRFFLump : public FUncompressedLump
|
||||
{
|
||||
virtual FileReader *GetReader();
|
||||
virtual int FillCache();
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// BloodCrypt
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void BloodCrypt (void *data, int key, int len)
|
||||
{
|
||||
int p = (BYTE)key, i;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
((BYTE *)data)[i] ^= (unsigned char)(p+(i>>1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Blood RFF file
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FRFFFile : public FResourceFile
|
||||
{
|
||||
FRFFLump *Lumps;
|
||||
|
||||
public:
|
||||
FRFFFile(const char * filename, FileReader *file);
|
||||
virtual ~FRFFFile();
|
||||
virtual bool Open();
|
||||
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
|
||||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Initializes a Blood RFF file
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FRFFFile::FRFFFile(const char *filename, FileReader *file)
|
||||
: FResourceFile(filename, file)
|
||||
{
|
||||
Lumps = NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Initializes a Blood RFF file
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FRFFFile::Open()
|
||||
{
|
||||
RFFLump *lumps;
|
||||
RFFInfo header;
|
||||
|
||||
Reader->Read(&header, sizeof(header));
|
||||
|
||||
NumLumps = LittleLong(header.NumLumps);
|
||||
header.DirOfs = LittleLong(header.DirOfs);
|
||||
lumps = new RFFLump[header.NumLumps];
|
||||
Reader->Seek (header.DirOfs, SEEK_SET);
|
||||
Reader->Read (lumps, header.NumLumps * sizeof(RFFLump));
|
||||
BloodCrypt (lumps, header.DirOfs, header.NumLumps * sizeof(RFFLump));
|
||||
|
||||
Lumps = new FRFFLump[NumLumps];
|
||||
|
||||
Printf(", %d lumps\n", NumLumps);
|
||||
for (DWORD i = 0; i < NumLumps; ++i)
|
||||
{
|
||||
if (lumps[i].Extension[0] == 'S' && lumps[i].Extension[1] == 'F' &&
|
||||
lumps[i].Extension[2] == 'X')
|
||||
{
|
||||
Lumps[i].Namespace = ns_bloodsfx;
|
||||
}
|
||||
else if (lumps[i].Extension[0] == 'R' && lumps[i].Extension[1] == 'A' &&
|
||||
lumps[i].Extension[2] == 'W')
|
||||
{
|
||||
Lumps[i].Namespace = ns_bloodraw;
|
||||
}
|
||||
else
|
||||
{
|
||||
Lumps[i].Namespace = ns_global;
|
||||
}
|
||||
|
||||
Lumps[i].Position = LittleLong(lumps[i].FilePos);
|
||||
Lumps[i].LumpSize = LittleLong(lumps[i].Size);
|
||||
Lumps[i].Owner = this;
|
||||
if (lumps[i].Flags & 0x10) Lumps[i].Flags |= LUMPF_BLOODCRYPT;
|
||||
|
||||
// Rearrange the name and extension in a part of the lump record
|
||||
// that I don't have any use for in order to cnstruct the fullname.
|
||||
lumps[i].Name[8] = '\0';
|
||||
strcpy ((char *)lumps[i].IDontKnow, lumps[i].Name);
|
||||
strcat ((char *)lumps[i].IDontKnow, ".");
|
||||
strcat ((char *)lumps[i].IDontKnow, lumps[i].Extension);
|
||||
Lumps[i].LumpNameSetup((char *)lumps[i].IDontKnow);
|
||||
}
|
||||
delete[] lumps;
|
||||
return true;
|
||||
}
|
||||
|
||||
FRFFFile::~FRFFFile()
|
||||
{
|
||||
if (Lumps != NULL) delete [] Lumps;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Get reader (only returns non-NULL if not encrypted)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FileReader *FRFFLump::GetReader()
|
||||
{
|
||||
// Don't return the reader if this lump is encrypted
|
||||
// In that case always force caching of the lump
|
||||
if (!(Flags & LUMPF_BLOODCRYPT)) return FUncompressedLump::GetReader();
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Fills the lump cache and performs decryption
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FRFFLump::FillCache()
|
||||
{
|
||||
int res = FUncompressedLump::FillCache();
|
||||
|
||||
if (Flags & LUMPF_BLOODCRYPT)
|
||||
{
|
||||
int cryptlen = MIN<int> (LumpSize, 256);
|
||||
BYTE *data = (BYTE *)Cache;
|
||||
|
||||
for (int i = 0; i < cryptlen; ++i)
|
||||
{
|
||||
data[i] ^= i >> 1;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// File open
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FResourceFile *CheckRFF(const char *filename, FileReader *file)
|
||||
{
|
||||
char head[4];
|
||||
|
||||
file->Seek(0, SEEK_SET);
|
||||
file->Read(&head, 4);
|
||||
file->Seek(0, SEEK_SET);
|
||||
if (!memcmp(head, "RFF\x1a", 4))
|
||||
{
|
||||
FResourceFile *rf = new FRFFFile(filename, file);
|
||||
if (rf->Open()) return rf;
|
||||
delete rf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
332
src/resourcefiles/file_wad.cpp
Normal file
332
src/resourcefiles/file_wad.cpp
Normal file
|
@ -0,0 +1,332 @@
|
|||
/*
|
||||
** file_wad.cpp
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2009 Randy Heit
|
||||
** Copyright 2005-2009 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
#include "resourcefile.h"
|
||||
#include "cmdlib.h"
|
||||
#include "v_text.h"
|
||||
#include "w_wad.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Wad file
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FWadFile : public FUncompressedFile
|
||||
{
|
||||
bool IsMarker(int lump, const char *marker);
|
||||
void SetNamespace(const char *startmarker, const char *endmarker, namespace_t space, bool flathack=false);
|
||||
void SkinHack ();
|
||||
|
||||
public:
|
||||
FWadFile(const char * filename, FileReader *file);
|
||||
void FindStrifeTeaserVoices ();
|
||||
bool Open();
|
||||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FWadFile::FWadFile
|
||||
//
|
||||
// Initializes a WAD file
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FWadFile::FWadFile(const char *filename, FileReader *file) : FUncompressedFile(filename, file)
|
||||
{
|
||||
Lumps = NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Open it
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FWadFile::Open()
|
||||
{
|
||||
wadinfo_t header;
|
||||
|
||||
Reader->Read(&header, sizeof(header));
|
||||
NumLumps = LittleLong(header.NumLumps);
|
||||
header.InfoTableOfs = LittleLong(header.InfoTableOfs);
|
||||
|
||||
wadlump_t *fileinfo = new wadlump_t[NumLumps];
|
||||
Reader->Seek (header.InfoTableOfs, SEEK_SET);
|
||||
Reader->Read (fileinfo, NumLumps * sizeof(wadlump_t));
|
||||
|
||||
Lumps = new FUncompressedLump[NumLumps];
|
||||
|
||||
Printf(", %d lumps\n", NumLumps);
|
||||
|
||||
for(DWORD i = 0; i < NumLumps; i++)
|
||||
{
|
||||
uppercopy (Lumps[i].Name, fileinfo[i].Name);
|
||||
Lumps[i].Name[8] = 0;
|
||||
Lumps[i].Owner = this;
|
||||
Lumps[i].Position = LittleLong(fileinfo[i].FilePos);
|
||||
Lumps[i].LumpSize = LittleLong(fileinfo[i].Size);
|
||||
Lumps[i].Namespace = ns_global;
|
||||
Lumps[i].Flags = 0;
|
||||
Lumps[i].FullName = NULL;
|
||||
}
|
||||
|
||||
SetNamespace("S_START", "S_END", ns_sprites);
|
||||
SetNamespace("F_START", "F_END", ns_flats, true);
|
||||
SetNamespace("C_START", "C_END", ns_colormaps);
|
||||
SetNamespace("A_START", "A_END", ns_acslibrary);
|
||||
SetNamespace("TX_START", "TX_END", ns_newtextures);
|
||||
SetNamespace("V_START", "V_END", ns_strifevoices);
|
||||
SetNamespace("HI_START", "HI_END", ns_hires);
|
||||
SkinHack();
|
||||
delete [] fileinfo;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// IsMarker
|
||||
//
|
||||
// (from BOOM)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
inline bool FWadFile::IsMarker(int lump, const char *marker)
|
||||
{
|
||||
if (Lumps[lump].Name[0] == marker[0])
|
||||
{
|
||||
return (!strcmp(Lumps[lump].Name, marker) ||
|
||||
(marker[1] == '_' && !strcmp(Lumps[lump].Name+1, marker)));
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SetNameSpace
|
||||
//
|
||||
// Sets namespace information for the lumps. It always looks for the first
|
||||
// x_START and the last x_END lump, except when loading flats. In this case
|
||||
// F_START may be absent and if that is the case all lumps with a size of
|
||||
// 4096 will be flagged appropriately.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, namespace_t space, bool flathack)
|
||||
{
|
||||
int start=-1, end=-1;
|
||||
bool warned = false;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < (int)NumLumps; i++)
|
||||
{
|
||||
if (IsMarker(i, startmarker))
|
||||
{
|
||||
start = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flathack && start == -1) return;
|
||||
|
||||
for(i = NumLumps-1; i > start; i--)
|
||||
{
|
||||
if (IsMarker(i, endmarker))
|
||||
{
|
||||
end = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (end == -1) return;
|
||||
|
||||
if (start != -1)
|
||||
{
|
||||
for(int i = start+1; i < end; i++)
|
||||
{
|
||||
if (Lumps[i].Namespace != ns_global)
|
||||
{
|
||||
if (!warned)
|
||||
{
|
||||
Printf(TEXTCOLOR_YELLOW"WARNING: Overlapping namespaces found.\n");
|
||||
}
|
||||
warned = true;
|
||||
}
|
||||
else if (IsMarker(i, startmarker))
|
||||
{
|
||||
Printf(TEXTCOLOR_YELLOW"WARNING: Multiple %s markers found.\n", startmarker);
|
||||
}
|
||||
else if (IsMarker(i, endmarker))
|
||||
{
|
||||
Printf(TEXTCOLOR_YELLOW"WARNING: Multiple %s markers found.\n", endmarker);
|
||||
}
|
||||
else
|
||||
{
|
||||
Lumps[i].Namespace = space;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (flathack)
|
||||
{
|
||||
Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", endmarker, startmarker);
|
||||
for(int i = 0; i < end; i++)
|
||||
{
|
||||
if (Lumps[i].LumpSize == 4096)
|
||||
{
|
||||
// We can't add this to the flats namespace but
|
||||
// it needs to be flagged for the texture manager.
|
||||
Lumps[i].Flags |= LUMPF_MAYBEFLAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_SkinHack
|
||||
//
|
||||
// Tests a wad file to see if it contains an S_SKIN marker. If it does,
|
||||
// every lump in the wad is moved into a new namespace. Because skins are
|
||||
// only supposed to replace player sprites, sounds, or faces, this should
|
||||
// not be a problem. Yes, there are skins that replace more than that, but
|
||||
// they are such a pain, and breaking them like this was done on purpose.
|
||||
// This also renames any S_SKINxx lumps to just S_SKIN.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FWadFile::SkinHack ()
|
||||
{
|
||||
static int namespc = ns_firstskin;
|
||||
bool skinned = false;
|
||||
bool hasmap = false;
|
||||
DWORD i;
|
||||
|
||||
for (i = 0; i < NumLumps; i++)
|
||||
{
|
||||
FResourceLump *lump = &Lumps[i];
|
||||
|
||||
if (lump->Name[0] == 'S' &&
|
||||
lump->Name[1] == '_' &&
|
||||
lump->Name[2] == 'S' &&
|
||||
lump->Name[3] == 'K' &&
|
||||
lump->Name[4] == 'I' &&
|
||||
lump->Name[5] == 'N')
|
||||
{ // Wad has at least one skin.
|
||||
lump->Name[6] = lump->Name[7] = 0;
|
||||
if (!skinned)
|
||||
{
|
||||
skinned = true;
|
||||
DWORD j;
|
||||
|
||||
for (j = 0; j < NumLumps; j++)
|
||||
{
|
||||
Lumps[j].Namespace = namespc;
|
||||
}
|
||||
namespc++;
|
||||
}
|
||||
}
|
||||
if (lump->Name[0] == 'M' &&
|
||||
lump->Name[1] == 'A' &&
|
||||
lump->Name[2] == 'P')
|
||||
{
|
||||
hasmap = true;
|
||||
}
|
||||
}
|
||||
if (skinned && hasmap)
|
||||
{
|
||||
Printf (TEXTCOLOR_BLUE
|
||||
"The maps in %s will not be loaded because it has a skin.\n"
|
||||
TEXTCOLOR_BLUE
|
||||
"You should remove the skin from the wad to play these maps.\n",
|
||||
Filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FindStrifeTeaserVoices
|
||||
//
|
||||
// Strife0.wad does not have the voices between V_START/V_END markers, so
|
||||
// figure out which lumps are voices based on their names.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FWadFile::FindStrifeTeaserVoices ()
|
||||
{
|
||||
for (DWORD i = 0; i <= NumLumps; ++i)
|
||||
{
|
||||
if (Lumps[i].Name[0] == 'V' &&
|
||||
Lumps[i].Name[1] == 'O' &&
|
||||
Lumps[i].Name[2] == 'C')
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 3; j < 8; ++j)
|
||||
{
|
||||
if (Lumps[i].Name[j] != 0 && !isdigit(Lumps[i].Name[j]))
|
||||
break;
|
||||
}
|
||||
if (j == 8)
|
||||
{
|
||||
Lumps[i].Namespace = ns_strifevoices;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// File open
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FResourceFile *CheckWad(const char *filename, FileReader *file)
|
||||
{
|
||||
char head[4];
|
||||
|
||||
file->Seek(0, SEEK_SET);
|
||||
file->Read(&head, 4);
|
||||
file->Seek(0, SEEK_SET);
|
||||
if (!memcmp(head, "IWAD", 4) || !memcmp(head, "PWAD", 4))
|
||||
{
|
||||
FResourceFile *rf = new FWadFile(filename, file);
|
||||
if (rf->Open()) return rf;
|
||||
delete rf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
407
src/resourcefiles/file_zip.cpp
Normal file
407
src/resourcefiles/file_zip.cpp
Normal file
|
@ -0,0 +1,407 @@
|
|||
/*
|
||||
** file_zip.cpp
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2009 Randy Heit
|
||||
** Copyright 2005-2009 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
#include "resourcefile.h"
|
||||
#include "cmdlib.h"
|
||||
#include "templates.h"
|
||||
#include "v_text.h"
|
||||
#include "w_wad.h"
|
||||
#include "w_zip.h"
|
||||
#include "i_system.h"
|
||||
|
||||
#define BUFREADCOMMENT (0x400)
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
//
|
||||
// Finds the central directory end record in the end of the file.
|
||||
// Taken from Quake3 source but the file in question is not GPL'ed. ;)
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
static DWORD Zip_FindCentralDir(FileReader * fin)
|
||||
{
|
||||
unsigned char buf[BUFREADCOMMENT + 4];
|
||||
DWORD FileSize;
|
||||
DWORD uBackRead;
|
||||
DWORD uMaxBack; // maximum size of global comment
|
||||
DWORD uPosFound=0;
|
||||
|
||||
fin->Seek(0, SEEK_END);
|
||||
|
||||
FileSize = fin->Tell();
|
||||
uMaxBack = MIN<DWORD>(0xffff, FileSize);
|
||||
|
||||
uBackRead = 4;
|
||||
while (uBackRead < uMaxBack)
|
||||
{
|
||||
DWORD uReadSize, uReadPos;
|
||||
int i;
|
||||
if (uBackRead + BUFREADCOMMENT > uMaxBack)
|
||||
uBackRead = uMaxBack;
|
||||
else
|
||||
uBackRead += BUFREADCOMMENT;
|
||||
uReadPos = FileSize - uBackRead;
|
||||
|
||||
uReadSize = MIN<DWORD>((BUFREADCOMMENT + 4), (FileSize - uReadPos));
|
||||
|
||||
if (fin->Seek(uReadPos, SEEK_SET) != 0) break;
|
||||
|
||||
if (fin->Read(buf, (SDWORD)uReadSize) != (SDWORD)uReadSize) break;
|
||||
|
||||
for (i = (int)uReadSize - 3; (i--) > 0;)
|
||||
{
|
||||
if (buf[i] == 'P' && buf[i+1] == 'K' && buf[i+2] == 5 && buf[i+3] == 6)
|
||||
{
|
||||
uPosFound = uReadPos + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (uPosFound != 0)
|
||||
break;
|
||||
}
|
||||
return uPosFound;
|
||||
}
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
LUMPFZIP_NEEDFILESTART = 128
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Zip Lump
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
struct FZipLump : public FResourceLump
|
||||
{
|
||||
BYTE Method;
|
||||
int CompressedSize;
|
||||
int Position;
|
||||
|
||||
virtual FileReader *GetReader();
|
||||
virtual int FillCache();
|
||||
|
||||
private:
|
||||
void SetLumpAddress();
|
||||
virtual int GetFileOffset()
|
||||
{
|
||||
if (Method != METHOD_STORED) return -1;
|
||||
if (Flags & LUMPFZIP_NEEDFILESTART) SetLumpAddress(); return Position;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Zip file
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FZipFile : public FResourceFile
|
||||
{
|
||||
FZipLump *Lumps;
|
||||
|
||||
static int STACK_ARGS lumpcmp(const void * a, const void * b);
|
||||
|
||||
public:
|
||||
FZipFile(const char * filename, FileReader *file);
|
||||
virtual ~FZipFile();
|
||||
bool Open();
|
||||
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
int STACK_ARGS FZipFile::lumpcmp(const void * a, const void * b)
|
||||
{
|
||||
FZipLump * rec1 = (FZipLump *)a;
|
||||
FZipLump * rec2 = (FZipLump *)b;
|
||||
|
||||
return stricmp(rec1->FullName, rec2->FullName);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Zip file
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FZipFile::FZipFile(const char * filename, FileReader *file)
|
||||
: FResourceFile(filename, file)
|
||||
{
|
||||
Lumps = NULL;
|
||||
}
|
||||
|
||||
bool FZipFile::Open()
|
||||
{
|
||||
DWORD centraldir = Zip_FindCentralDir(Reader);
|
||||
FZipEndOfCentralDirectory info;
|
||||
int skipped = 0;
|
||||
|
||||
Lumps = NULL;
|
||||
|
||||
if (centraldir == 0)
|
||||
{
|
||||
Printf("\n%s: ZIP file corrupt!\n", Filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the central directory info.
|
||||
Reader->Seek(centraldir, SEEK_SET);
|
||||
Reader->Read(&info, sizeof(FZipEndOfCentralDirectory));
|
||||
|
||||
// No multi-disk zips!
|
||||
if (info.NumEntries != info.NumEntriesOnAllDisks ||
|
||||
info.FirstDisk != 0 || info.DiskNumber != 0)
|
||||
{
|
||||
Printf("\n%s: Multipart Zip files are not supported.\n", Filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
NumLumps = LittleShort(info.NumEntries);
|
||||
Lumps = new FZipLump[NumLumps];
|
||||
|
||||
// Load the entire central directory. Too bad that this contains variable length entries...
|
||||
void *directory = malloc(LittleLong(info.DirectorySize));
|
||||
Reader->Seek(LittleLong(info.DirectoryOffset), SEEK_SET);
|
||||
Reader->Read(directory, LittleLong(info.DirectorySize));
|
||||
|
||||
char *dirptr = (char*)directory;
|
||||
FZipLump *lump_p = Lumps;
|
||||
for (int i = 0; i < NumLumps; i++)
|
||||
{
|
||||
FZipCentralDirectoryInfo *zip_fh = (FZipCentralDirectoryInfo *)dirptr;
|
||||
|
||||
char name[256];
|
||||
|
||||
int len = LittleShort(zip_fh->NameLength);
|
||||
strncpy(name, dirptr + sizeof(FZipCentralDirectoryInfo), MIN<int>(len, 255));
|
||||
name[len] = 0;
|
||||
dirptr += sizeof(FZipCentralDirectoryInfo) +
|
||||
LittleShort(zip_fh->NameLength) +
|
||||
LittleShort(zip_fh->ExtraLength) +
|
||||
LittleShort(zip_fh->CommentLength);
|
||||
|
||||
// skip Directories
|
||||
if(name[len - 1] == '/' && LittleLong(zip_fh->UncompressedSize) == 0)
|
||||
{
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore unknown compression formats
|
||||
zip_fh->Method = LittleShort(zip_fh->Method);
|
||||
if (zip_fh->Method != METHOD_STORED &&
|
||||
zip_fh->Method != METHOD_DEFLATE &&
|
||||
zip_fh->Method != METHOD_LZMA &&
|
||||
zip_fh->Method != METHOD_BZIP2)
|
||||
{
|
||||
Printf("\n%s: '%s' uses an unsupported compression algorithm (#%d).\n", Filename, name, zip_fh->Method);
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
// Also ignore encrypted entries
|
||||
if(LittleShort(zip_fh->Flags) & ZF_ENCRYPTED)
|
||||
{
|
||||
Printf("\n%s: '%s' is encrypted. Encryption is not supported.\n", Filename, name);
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
FixPathSeperator(name);
|
||||
strlwr(name);
|
||||
|
||||
lump_p->LumpNameSetup(name);
|
||||
lump_p->LumpSize = LittleLong(zip_fh->UncompressedSize);
|
||||
lump_p->Owner = this;
|
||||
// The start of the Reader will be determined the first time it is accessed.
|
||||
lump_p->Flags = LUMPF_ZIPFILE | LUMPFZIP_NEEDFILESTART;
|
||||
lump_p->Method = zip_fh->Method;
|
||||
lump_p->CompressedSize = LittleLong(zip_fh->CompressedSize);
|
||||
lump_p->Position = LittleLong(zip_fh->LocalHeaderOffset);
|
||||
lump_p->CheckEmbedded();
|
||||
lump_p++;
|
||||
}
|
||||
// Resize the lump record array to its actual size
|
||||
NumLumps -= skipped;
|
||||
free(directory);
|
||||
//LumpInfo.Resize(NumLumps);
|
||||
Printf(", %d lumps\n", NumLumps);
|
||||
|
||||
// Entries in Zips are sorted alphabetically.
|
||||
qsort(Lumps, NumLumps, sizeof(FZipLump), lumpcmp);
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Zip file
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FZipFile::~FZipFile()
|
||||
{
|
||||
if (Lumps != NULL) delete [] Lumps;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SetLumpAddress
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FZipLump::SetLumpAddress()
|
||||
{
|
||||
// This file is inside a zip and has not been opened before.
|
||||
// Position points to the start of the local file header, which we must
|
||||
// read and skip so that we can get to the actual file data.
|
||||
FZipLocalFileHeader localHeader;
|
||||
int skiplen;
|
||||
|
||||
FileReader *file = Owner->Reader;
|
||||
|
||||
file->Seek(Position, SEEK_SET);
|
||||
file->Read(&localHeader, sizeof(localHeader));
|
||||
skiplen = LittleShort(localHeader.NameLength) + LittleShort(localHeader.ExtraLength);
|
||||
Position += sizeof(localHeader) + skiplen;
|
||||
Flags &= ~LUMPFZIP_NEEDFILESTART;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Get reader (only returns non-NULL if not encrypted)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FileReader *FZipLump::GetReader()
|
||||
{
|
||||
// Don't return the reader if this lump is encrypted
|
||||
// In that case always force caching of the lump
|
||||
if (Method == METHOD_STORED)
|
||||
{
|
||||
if (Flags & LUMPFZIP_NEEDFILESTART) SetLumpAddress();
|
||||
Owner->Reader->Seek(Position, SEEK_SET);
|
||||
return Owner->Reader;
|
||||
}
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Fills the lump cache and performs decompression
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FZipLump::FillCache()
|
||||
{
|
||||
if (Flags & LUMPFZIP_NEEDFILESTART) SetLumpAddress();
|
||||
const char *buffer;
|
||||
|
||||
if (Method == METHOD_STORED && (buffer = Owner->Reader->GetBuffer()) != NULL)
|
||||
{
|
||||
// This is an in-memory file so the cache can point directly to the file's data.
|
||||
Cache = const_cast<char*>(buffer) + Position;
|
||||
RefCount = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Owner->Reader->Seek(Position, SEEK_SET);
|
||||
Cache = new char[LumpSize];
|
||||
switch (Method)
|
||||
{
|
||||
case METHOD_STORED:
|
||||
{
|
||||
Owner->Reader->Read(Cache, LumpSize);
|
||||
break;
|
||||
}
|
||||
|
||||
case METHOD_DEFLATE:
|
||||
{
|
||||
FileReaderZ frz(*Owner->Reader, true);
|
||||
frz.Read(Cache, LumpSize);
|
||||
break;
|
||||
}
|
||||
|
||||
case METHOD_BZIP2:
|
||||
{
|
||||
FileReaderBZ2 frz(*Owner->Reader);
|
||||
frz.Read(Cache, LumpSize);
|
||||
break;
|
||||
}
|
||||
|
||||
case METHOD_LZMA:
|
||||
{
|
||||
FileReaderLZMA frz(*Owner->Reader, LumpSize, true);
|
||||
frz.Read(Cache, LumpSize);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
RefCount = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// File open
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FResourceFile *CheckZip(const char *filename, FileReader *file)
|
||||
{
|
||||
char head[4];
|
||||
|
||||
file->Seek(0, SEEK_SET);
|
||||
file->Read(&head, 4);
|
||||
file->Seek(0, SEEK_SET);
|
||||
if (!memcmp(head, "PK\x3\x4", 4))
|
||||
{
|
||||
FResourceFile *rf = new FZipFile(filename, file);
|
||||
if (rf->Open()) return rf;
|
||||
delete rf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
384
src/resourcefiles/resourcefile.cpp
Normal file
384
src/resourcefiles/resourcefile.cpp
Normal file
|
@ -0,0 +1,384 @@
|
|||
/*
|
||||
** resourcefile.cpp
|
||||
**
|
||||
** Base classes for resource file management
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2009 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
#include "resourcefile.h"
|
||||
#include "cmdlib.h"
|
||||
#include "w_wad.h"
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FileReader that reads from a lump's cache
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FLumpReader : public MemoryReader
|
||||
{
|
||||
FResourceLump *source;
|
||||
|
||||
public:
|
||||
FLumpReader(FResourceLump *src)
|
||||
: MemoryReader(NULL, src->LumpSize), source(src)
|
||||
{
|
||||
src->CacheLump();
|
||||
bufptr = src->Cache;
|
||||
}
|
||||
|
||||
~FLumpReader()
|
||||
{
|
||||
source->ReleaseCache();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Base class for resource lumps
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FResourceLump::~FResourceLump()
|
||||
{
|
||||
if (FullName != NULL)
|
||||
{
|
||||
delete [] FullName;
|
||||
FullName = NULL;
|
||||
}
|
||||
if (Cache != NULL)
|
||||
{
|
||||
delete [] Cache;
|
||||
Cache = NULL;
|
||||
}
|
||||
Owner = NULL;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets up the lump name information for anything not coming from a WAD file.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FResourceLump::LumpNameSetup(char *iname)
|
||||
{
|
||||
char base[256];
|
||||
char *lname = strrchr(iname,'/');
|
||||
lname = (lname == NULL) ? iname : lname + 1;
|
||||
strcpy(base, lname);
|
||||
char *dot = strrchr(base, '.');
|
||||
if (dot != NULL)
|
||||
{
|
||||
*dot = 0;
|
||||
}
|
||||
uppercopy(Name, base);
|
||||
Name[8] = 0;
|
||||
FullName = copystring(iname);
|
||||
|
||||
// Map some directories to WAD namespaces.
|
||||
// Note that some of these namespaces don't exist in WADS.
|
||||
// CheckNumForName will handle any request for these namespaces accordingly.
|
||||
Namespace = !strncmp(iname, "flats/", 6) ? ns_flats :
|
||||
!strncmp(iname, "textures/", 9) ? ns_newtextures :
|
||||
!strncmp(iname, "hires/", 6) ? ns_hires :
|
||||
!strncmp(iname, "sprites/", 8) ? ns_sprites :
|
||||
!strncmp(iname, "colormaps/", 10) ? ns_colormaps :
|
||||
!strncmp(iname, "acs/", 4) ? ns_acslibrary :
|
||||
!strncmp(iname, "voices/", 7) ? ns_strifevoices :
|
||||
!strncmp(iname, "patches/", 8) ? ns_patches :
|
||||
!strncmp(iname, "graphics/", 9) ? ns_graphics :
|
||||
!strncmp(iname, "sounds/", 7) ? ns_sounds :
|
||||
!strncmp(iname, "music/", 6) ? ns_music :
|
||||
!strchr(iname, '/') ? ns_global :
|
||||
-1;
|
||||
|
||||
// Anything that is not in one of these subdirectories or the main directory
|
||||
// should not be accessible through the standard WAD functions but only through
|
||||
// the ones which look for the full name.
|
||||
if (Namespace == -1)
|
||||
{
|
||||
memset(Name, 0, 8);
|
||||
}
|
||||
|
||||
// Since '\' can't be used as a file name's part inside a ZIP
|
||||
// we have to work around this for sprites because it is a valid
|
||||
// frame character.
|
||||
else if (Namespace == ns_sprites)
|
||||
{
|
||||
char *c;
|
||||
|
||||
while ((c = (char*)memchr(Name, '^', 8)))
|
||||
{
|
||||
*c = '\\';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FResourceLump::CheckEmbedded()
|
||||
{
|
||||
// Checks for embedded archives
|
||||
const char *c = strstr(Name, ".wad");
|
||||
if (c && strlen(c) == 4 && !strchr(Name, '/'))
|
||||
{
|
||||
// Mark all embedded WADs
|
||||
Flags |= LUMPF_EMBEDDED;
|
||||
}
|
||||
/* later
|
||||
else
|
||||
{
|
||||
if (c==NULL) c = strstr(Name, ".zip");
|
||||
if (c==NULL) c = strstr(Name, ".pk3");
|
||||
if (c==NULL) c = strstr(Name, ".7z");
|
||||
if (c && strlen(c) <= 4)
|
||||
{
|
||||
// Mark all embedded archives in any directory
|
||||
Flags |= LUMPF_EMBEDDED;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Returns the owner's FileReader if it can be used to access this lump
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FileReader *FResourceLump::GetReader()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Returns a file reader to the lump's cache
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FileReader *FResourceLump::NewReader()
|
||||
{
|
||||
return new FLumpReader(this);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Caches a lump's content and increases the reference counter
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void *FResourceLump::CacheLump()
|
||||
{
|
||||
if (Cache != NULL)
|
||||
{
|
||||
if (RefCount > 0) RefCount++;
|
||||
}
|
||||
else if (LumpSize > 0)
|
||||
{
|
||||
FillCache();
|
||||
}
|
||||
return Cache;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Decrements reference counter and frees lump if counter reaches 0
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FResourceLump::ReleaseCache()
|
||||
{
|
||||
if (LumpSize > 0 && RefCount > 0)
|
||||
{
|
||||
if (--RefCount == 0)
|
||||
{
|
||||
delete [] Cache;
|
||||
Cache = NULL;
|
||||
}
|
||||
}
|
||||
return RefCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Resource file base class
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FResourceFile::FResourceFile(const char *filename, FileReader *r)
|
||||
{
|
||||
Filename = copystring(filename);
|
||||
Reader = r;
|
||||
}
|
||||
|
||||
|
||||
FResourceFile::~FResourceFile()
|
||||
{
|
||||
delete [] Filename;
|
||||
delete Reader;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Needs to be virtual in the base class. Implemented only for WADs
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FResourceFile::FindStrifeTeaserVoices ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Caches a lump's content and increases the reference counter
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FileReader *FUncompressedLump::GetReader()
|
||||
{
|
||||
Owner->Reader->Seek(Position, SEEK_SET);
|
||||
return Owner->Reader;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Caches a lump's content and increases the reference counter
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FUncompressedLump::FillCache()
|
||||
{
|
||||
const char * buffer = Owner->Reader->GetBuffer();
|
||||
|
||||
if (buffer != NULL)
|
||||
{
|
||||
// This is an in-memory file so the cache can point directly to the file's data.
|
||||
Cache = const_cast<char*>(buffer) + Position;
|
||||
RefCount = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Owner->Reader->Seek(Position, SEEK_SET);
|
||||
Cache = new char[LumpSize];
|
||||
Owner->Reader->Read(Cache, LumpSize);
|
||||
RefCount = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Base class for uncompressed resource files
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FUncompressedFile::FUncompressedFile(const char *filename, FileReader *r)
|
||||
: FResourceFile(filename, r)
|
||||
{
|
||||
Lumps = NULL;
|
||||
}
|
||||
|
||||
FUncompressedFile::~FUncompressedFile()
|
||||
{
|
||||
if (Lumps != NULL) delete [] Lumps;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// external lump
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FExternalLump::FExternalLump(const char *_filename, int filesize)
|
||||
{
|
||||
filename = _filename? copystring(_filename) : NULL;
|
||||
|
||||
if (filesize == -1)
|
||||
{
|
||||
FILE *f = fopen(_filename,"rb");
|
||||
if (f != NULL)
|
||||
{
|
||||
fseek(f, 0, SEEK_END);
|
||||
LumpSize = ftell(f);
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
LumpSize = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LumpSize = filesize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FExternalLump::~FExternalLump()
|
||||
{
|
||||
if (filename != NULL) delete [] filename;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Caches a lump's content and increases the reference counter
|
||||
// For external lumps this reopens the file each time it is accessed
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FExternalLump::FillCache()
|
||||
{
|
||||
Cache = new char[LumpSize];
|
||||
FILE *f = fopen(filename, "rb");
|
||||
if (f != NULL)
|
||||
{
|
||||
fread(Cache, 1, LumpSize, f);
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(Cache, 0, LumpSize);
|
||||
}
|
||||
RefCount = 1;
|
||||
return 1;
|
||||
}
|
||||
|
115
src/resourcefiles/resourcefile.h
Normal file
115
src/resourcefiles/resourcefile.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
|
||||
|
||||
#ifndef __RESFILE_H
|
||||
#define __RESFILE_H
|
||||
|
||||
#include "files.h"
|
||||
|
||||
class FResourceFile;
|
||||
|
||||
struct FResourceLump
|
||||
{
|
||||
friend class FResourceFile;
|
||||
|
||||
int LumpSize;
|
||||
char * FullName; // only valid for files loaded from a .zip file
|
||||
char Name[9];
|
||||
BYTE Flags;
|
||||
BYTE RefCount;
|
||||
char * Cache;
|
||||
FResourceFile * Owner;
|
||||
int Namespace;
|
||||
|
||||
FResourceLump()
|
||||
{
|
||||
FullName = NULL;
|
||||
Cache = NULL;
|
||||
Owner = NULL;
|
||||
Flags = 0;
|
||||
RefCount = 0;
|
||||
Namespace = 0; // ns_global
|
||||
*Name = 0;
|
||||
}
|
||||
|
||||
virtual ~FResourceLump();
|
||||
virtual FileReader *GetReader();
|
||||
virtual FileReader *NewReader();
|
||||
virtual int GetFileOffset() { return -1; }
|
||||
void LumpNameSetup(char *iname);
|
||||
void CheckEmbedded();
|
||||
|
||||
void *CacheLump();
|
||||
int ReleaseCache();
|
||||
|
||||
protected:
|
||||
virtual int FillCache() = 0;
|
||||
|
||||
};
|
||||
|
||||
class FResourceFile
|
||||
{
|
||||
public:
|
||||
FileReader *Reader;
|
||||
const char *Filename;
|
||||
protected:
|
||||
DWORD NumLumps;
|
||||
|
||||
FResourceFile(const char *filename, FileReader *r);
|
||||
|
||||
private:
|
||||
DWORD FirstLump;
|
||||
|
||||
public:
|
||||
virtual ~FResourceFile();
|
||||
FileReader *GetReader() const { return Reader; }
|
||||
DWORD LumpCount() const { return NumLumps; }
|
||||
DWORD GetFirstLump() const { return FirstLump; }
|
||||
void SetFirstLump(DWORD f) { FirstLump = f; }
|
||||
|
||||
virtual void FindStrifeTeaserVoices ();
|
||||
virtual bool Open() = 0;
|
||||
virtual FResourceLump *GetLump(int no) = 0;
|
||||
};
|
||||
|
||||
struct FUncompressedLump : public FResourceLump
|
||||
{
|
||||
int Position;
|
||||
|
||||
virtual FileReader *GetReader();
|
||||
virtual int FillCache();
|
||||
virtual int GetFileOffset() { return Position; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Base class for uncompressed resource files (WAD, GRP, PAK and single lumps)
|
||||
class FUncompressedFile : public FResourceFile
|
||||
{
|
||||
protected:
|
||||
FUncompressedLump * Lumps;
|
||||
|
||||
|
||||
FUncompressedFile(const char *filename, FileReader *r);
|
||||
virtual ~FUncompressedFile();
|
||||
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
|
||||
struct FExternalLump : public FResourceLump
|
||||
{
|
||||
const char *filename; // the actual file name. This is not necessarily the same as the lump name!
|
||||
|
||||
FExternalLump(const char *_filename, int filesize = -1);
|
||||
~FExternalLump();
|
||||
virtual int FillCache();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -377,30 +377,12 @@ void FTextureManager::ReplaceTexture (FTextureID picnum, FTexture *newtexture, b
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FTextureManager::AddGroup(int wadnum, const char * startlump, const char * endlump, int ns, int usetype)
|
||||
void FTextureManager::AddGroup(int wadnum, int ns, int usetype)
|
||||
{
|
||||
int firsttx;
|
||||
int lasttx;
|
||||
|
||||
if (startlump && endlump)
|
||||
{
|
||||
firsttx = Wads.CheckNumForName (startlump);
|
||||
lasttx = Wads.CheckNumForName (endlump);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there are no markers we have to search the entire lump directory... :(
|
||||
firsttx = 0;
|
||||
lasttx = Wads.GetNumLumps() - 1;
|
||||
}
|
||||
|
||||
int firsttx = Wads.GetFirstLump(wadnum);
|
||||
int lasttx = Wads.GetLastLump(wadnum);
|
||||
char name[9];
|
||||
|
||||
if (firsttx == -1 || lasttx == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
name[8] = 0;
|
||||
|
||||
// Go from first to last so that ANIMDEFS work as expected. However,
|
||||
|
@ -408,9 +390,9 @@ void FTextureManager::AddGroup(int wadnum, const char * startlump, const char *
|
|||
// later ones), the texture is only inserted if it is the one returned
|
||||
// by doing a check by name in the list of wads.
|
||||
|
||||
for (firsttx += 1; firsttx < lasttx; ++firsttx)
|
||||
for (; firsttx <= lasttx; ++firsttx)
|
||||
{
|
||||
if (Wads.GetLumpFile(firsttx) == wadnum && Wads.GetLumpNamespace(firsttx) == ns)
|
||||
if (Wads.GetLumpNamespace(firsttx) == ns)
|
||||
{
|
||||
Wads.GetLumpName (name, firsttx);
|
||||
|
||||
|
@ -420,6 +402,14 @@ void FTextureManager::AddGroup(int wadnum, const char * startlump, const char *
|
|||
}
|
||||
StartScreen->Progress();
|
||||
}
|
||||
else if (ns == ns_flats && Wads.GetLumpFlags(firsttx) & LUMPF_MAYBEFLAT)
|
||||
{
|
||||
if (Wads.CheckNumForName (name, ns) < firsttx)
|
||||
{
|
||||
CreateTexture (firsttx, usetype);
|
||||
}
|
||||
StartScreen->Progress();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -431,8 +421,9 @@ void FTextureManager::AddGroup(int wadnum, const char * startlump, const char *
|
|||
|
||||
void FTextureManager::AddHiresTextures (int wadnum)
|
||||
{
|
||||
int firsttx = Wads.CheckNumForName ("HI_START");
|
||||
int lasttx = Wads.CheckNumForName ("HI_END");
|
||||
int firsttx = Wads.GetFirstLump(wadnum);
|
||||
int lasttx = Wads.GetLastLump(wadnum);
|
||||
|
||||
char name[9];
|
||||
TArray<FTextureID> tlist;
|
||||
|
||||
|
@ -443,15 +434,15 @@ void FTextureManager::AddHiresTextures (int wadnum)
|
|||
|
||||
name[8] = 0;
|
||||
|
||||
for (firsttx += 1; firsttx < lasttx; ++firsttx)
|
||||
for (;firsttx <= lasttx; ++firsttx)
|
||||
{
|
||||
if (Wads.GetLumpFile(firsttx) == wadnum)
|
||||
if (Wads.GetLumpNamespace(firsttx) == ns_hires)
|
||||
{
|
||||
tlist.Clear();
|
||||
Wads.GetLumpName (name, firsttx);
|
||||
|
||||
if (Wads.CheckNumForName (name, ns_hires) == firsttx)
|
||||
{
|
||||
tlist.Clear();
|
||||
int amount = ListTextures(name, tlist);
|
||||
if (amount == 0)
|
||||
{
|
||||
|
@ -717,28 +708,27 @@ void FTextureManager::AddTexturesForWad(int wadnum)
|
|||
int lumpcount = Wads.GetNumLumps();
|
||||
|
||||
// First step: Load sprites
|
||||
AddGroup(wadnum, "S_START", "S_END", ns_sprites, FTexture::TEX_Sprite);
|
||||
AddGroup(wadnum, ns_sprites, FTexture::TEX_Sprite);
|
||||
|
||||
// When loading a Zip, all graphics in the patches/ directory should be
|
||||
// added as well.
|
||||
AddGroup(wadnum, NULL, NULL, ns_patches, FTexture::TEX_WallPatch);
|
||||
AddGroup(wadnum, ns_patches, FTexture::TEX_WallPatch);
|
||||
|
||||
// Second step: TEXTUREx lumps
|
||||
LoadTextureX(wadnum);
|
||||
|
||||
// Third step: Flats
|
||||
AddGroup(wadnum, "F_START", "F_END", ns_flats, FTexture::TEX_Flat);
|
||||
AddGroup(wadnum, ns_flats, FTexture::TEX_Flat);
|
||||
|
||||
// Fourth step: Textures (TX_)
|
||||
AddGroup(wadnum, "TX_START", "TX_END", ns_newtextures, FTexture::TEX_Override);
|
||||
AddGroup(wadnum, ns_newtextures, FTexture::TEX_Override);
|
||||
|
||||
// Sixth step: Try to find any lump in the WAD that may be a texture and load as a TEX_MiscPatch
|
||||
for (int i = 0; i < lumpcount; i++)
|
||||
{
|
||||
int file = Wads.GetLumpFile(i);
|
||||
if (file > wadnum) break; // lumps in the global namespace are ordered by WAD
|
||||
if (file < wadnum) continue;
|
||||
int firsttx = Wads.GetFirstLump(wadnum);
|
||||
int lasttx = Wads.GetLastLump(wadnum);
|
||||
|
||||
for (int i= firsttx; i <= lasttx; i++)
|
||||
{
|
||||
char name[9];
|
||||
Wads.GetLumpName(name, i);
|
||||
name[8]=0;
|
||||
|
@ -766,7 +756,7 @@ void FTextureManager::AddTexturesForWad(int wadnum)
|
|||
if (Wads.CheckLumpName(i, "BLOCKMAP")) continue;
|
||||
if (Wads.CheckLumpName(i, "BEHAVIOR")) continue;
|
||||
|
||||
// Don't bother looking this lump if something later overrides it.
|
||||
// Don't bother looking at this lump if something later overrides it.
|
||||
if (Wads.CheckNumForName(name, ns_graphics) != i) continue;
|
||||
|
||||
// skip this if it has already been added as a wall patch.
|
||||
|
|
|
@ -300,7 +300,7 @@ public:
|
|||
|
||||
void AddTexturesLump (const void *lumpdata, int lumpsize, int deflumpnum, int patcheslump, int firstdup=0, bool texture1=false);
|
||||
void AddTexturesLumps (int lump1, int lump2, int patcheslump);
|
||||
void AddGroup(int wadnum, const char * startlump, const char * endlump, int ns, int usetype);
|
||||
void AddGroup(int wadnum, int ns, int usetype);
|
||||
void AddPatches (int lumpnum);
|
||||
void AddTiles (void *tileFile);
|
||||
void AddHiresTextures (int wadnum);
|
||||
|
|
1787
src/w_wad.cpp
1787
src/w_wad.cpp
File diff suppressed because it is too large
Load diff
88
src/w_wad.h
88
src/w_wad.h
|
@ -27,26 +27,9 @@
|
|||
#include "doomdef.h"
|
||||
#include "tarray.h"
|
||||
|
||||
// [RH] Compare wad header as ints instead of chars
|
||||
#define IWAD_ID MAKE_ID('I','W','A','D')
|
||||
#define PWAD_ID MAKE_ID('P','W','A','D')
|
||||
#define RFF_ID MAKE_ID('R','F','F',0x1a)
|
||||
#define ZIP_ID MAKE_ID('P','K',3,4)
|
||||
#define GRP_ID_0 MAKE_ID('K','e','n','S')
|
||||
#define GRP_ID_1 MAKE_ID('i','l','v','e')
|
||||
#define GRP_ID_2 MAKE_ID('r','m','a','n')
|
||||
class FResourceFile;
|
||||
struct FResourceLump;
|
||||
|
||||
// [RH] Remove limit on number of WAD files
|
||||
struct wadlist_t
|
||||
{
|
||||
wadlist_t *next;
|
||||
char name[1]; // +size of string
|
||||
};
|
||||
extern wadlist_t *wadfiles;
|
||||
|
||||
//
|
||||
// TYPES
|
||||
//
|
||||
struct wadinfo_t
|
||||
{
|
||||
// Should be "IWAD" or "PWAD".
|
||||
|
@ -62,17 +45,18 @@ struct wadlump_t
|
|||
char Name[8];
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LUMPF_BLOODCRYPT = 1, // Lump uses Blood-style encryption
|
||||
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
|
||||
LUMPF_7ZFILE = 32, // Inside a 7z archive; position is its index in the archive
|
||||
};
|
||||
#define IWAD_ID MAKE_ID('I','W','A','D')
|
||||
#define PWAD_ID MAKE_ID('P','W','A','D')
|
||||
|
||||
|
||||
// [RH] Remove limit on number of WAD files
|
||||
struct wadlist_t
|
||||
{
|
||||
wadlist_t *next;
|
||||
char name[1]; // +size of string
|
||||
};
|
||||
extern wadlist_t *wadfiles;
|
||||
|
||||
// [RH] Namespaces from BOOM.
|
||||
typedef enum {
|
||||
ns_global = 0,
|
||||
|
@ -96,17 +80,22 @@ typedef enum {
|
|||
ns_patches,
|
||||
ns_graphics,
|
||||
ns_music,
|
||||
|
||||
ns_firstskin,
|
||||
} namespace_t;
|
||||
|
||||
enum ELumpFlags
|
||||
{
|
||||
LUMPF_MAYBEFLAT=1,
|
||||
LUMPF_ZIPFILE=2,
|
||||
LUMPF_EMBEDDED=4,
|
||||
LUMPF_BLOODCRYPT = 8,
|
||||
};
|
||||
|
||||
|
||||
// [RH] Copy an 8-char string and uppercase it.
|
||||
void uppercopy (char *to, const char *from);
|
||||
|
||||
// Perform Blood encryption/decryption.
|
||||
void BloodCrypt (void *data, int key, int len);
|
||||
|
||||
// Locate central directory in a zip file.
|
||||
DWORD Zip_FindCentralDir(FileReader * fin);
|
||||
|
||||
// A very loose reference to a lump on disk. This is really just a wrapper
|
||||
// around the main wad's FILE object with a different length recorded. Since
|
||||
// two lumps from the same wad share the same FILE, you cannot read from
|
||||
|
@ -126,13 +115,9 @@ public:
|
|||
char *Gets(char *strbuf, int len);
|
||||
|
||||
private:
|
||||
FWadLump (const FileReader &reader, long length, bool encrypted);
|
||||
FWadLump (FILE *file, long length);
|
||||
FWadLump (char * data, long length, bool destroy);
|
||||
FWadLump (FResourceLump *Lump, bool alwayscache = false);
|
||||
|
||||
char *SourceData;
|
||||
bool DestroySource;
|
||||
bool Encrypted;
|
||||
FResourceLump *Lump;
|
||||
|
||||
friend class FWadCollection;
|
||||
};
|
||||
|
@ -169,12 +154,15 @@ public:
|
|||
enum { IWAD_FILENUM = 1 };
|
||||
|
||||
void InitMultipleFiles (wadlist_t **filenames);
|
||||
void AddFile (const char *filename, const char *data=NULL, int length=-1);
|
||||
void AddFile (const char *filename, FileReader *wadinfo = NULL);
|
||||
int CheckIfWadLoaded (const char *name);
|
||||
|
||||
const char *GetWadName (int wadnum) const;
|
||||
const char *GetWadFullName (int wadnum) const;
|
||||
|
||||
int GetFirstLump(int wadnum) const;
|
||||
int GetLastLump(int wadnum) const;
|
||||
|
||||
int CheckNumForName (const char *name, int namespc);
|
||||
int CheckNumForName (const char *name, int namespc, int wadfile, bool exact = true);
|
||||
int GetNumForName (const char *name, int namespc);
|
||||
|
@ -225,36 +213,26 @@ public:
|
|||
int AddExternalFile(const char *filename);
|
||||
|
||||
protected:
|
||||
class WadFileRecord;
|
||||
|
||||
struct LumpRecord;
|
||||
|
||||
TArray<FResourceFile *> Files;
|
||||
TArray<LumpRecord> LumpInfo;
|
||||
|
||||
DWORD *FirstLumpIndex; // [RH] Hashing stuff moved out of lumpinfo structure
|
||||
DWORD *NextLumpIndex;
|
||||
|
||||
DWORD *FirstLumpIndex_FullName; // The same information for fully qualified paths from .zips
|
||||
DWORD *NextLumpIndex_FullName;
|
||||
|
||||
|
||||
TArray<LumpRecord> LumpInfo;
|
||||
TArray<WadFileRecord *> Wads;
|
||||
DWORD NumLumps; // Not necessarily the same as LumpInfo.Size()
|
||||
DWORD NumWads;
|
||||
|
||||
void SkinHack (int baselump);
|
||||
void InitHashChains (); // [RH] Set up the lumpinfo hashing
|
||||
|
||||
// [RH] Combine multiple marked ranges of lumps into one.
|
||||
int MergeLumps (const char *start, const char *end, int name_space);
|
||||
bool IsMarker (const LumpRecord *lump, const char *marker) const;
|
||||
void FindStrifeTeaserVoices ();
|
||||
|
||||
char *ReadZipLump(LumpRecord *l);
|
||||
|
||||
private:
|
||||
static int STACK_ARGS lumpcmp(const void * a, const void * b);
|
||||
void ScanForFlatHack (int startlump);
|
||||
void RenameSprites (int startlump);
|
||||
void SetLumpAddress(LumpRecord *l);
|
||||
void DeleteAll();
|
||||
};
|
||||
|
||||
|
|
|
@ -1648,8 +1648,7 @@ void WI_updateStats ()
|
|||
{
|
||||
WI_updateAnimatedBack ();
|
||||
|
||||
if ((!(gameinfo.gametype & GAME_DoomChex) || acceleratestage)
|
||||
&& sp_state != 10)
|
||||
if ((!gameinfo.intermissioncounter || acceleratestage) && sp_state != 10)
|
||||
{
|
||||
if (acceleratestage)
|
||||
{
|
||||
|
@ -1667,7 +1666,7 @@ void WI_updateStats ()
|
|||
|
||||
if (sp_state == 2)
|
||||
{
|
||||
if (gameinfo.gametype & GAME_DoomChex)
|
||||
if (gameinfo.intermissioncounter)
|
||||
{
|
||||
cnt_kills[0] += 2;
|
||||
|
||||
|
@ -1683,7 +1682,7 @@ void WI_updateStats ()
|
|||
}
|
||||
else if (sp_state == 4)
|
||||
{
|
||||
if (gameinfo.gametype & GAME_DoomChex)
|
||||
if (gameinfo.intermissioncounter)
|
||||
{
|
||||
cnt_items[0] += 2;
|
||||
|
||||
|
@ -1699,7 +1698,7 @@ void WI_updateStats ()
|
|||
}
|
||||
else if (sp_state == 6)
|
||||
{
|
||||
if (gameinfo.gametype & GAME_DoomChex)
|
||||
if (gameinfo.intermissioncounter)
|
||||
{
|
||||
cnt_secret[0] += 2;
|
||||
|
||||
|
@ -1715,7 +1714,7 @@ void WI_updateStats ()
|
|||
}
|
||||
else if (sp_state == 8)
|
||||
{
|
||||
if (gameinfo.gametype & GAME_DoomChex)
|
||||
if (gameinfo.intermissioncounter)
|
||||
{
|
||||
if (!(bcnt&3))
|
||||
S_Sound (CHAN_VOICE | CHAN_UI, "intermission/tick", 1, ATTN_NONE);
|
||||
|
|
|
@ -25,6 +25,7 @@ gameinfo
|
|||
backpacktype = "ZorchPack"
|
||||
statusbar = "sbarinfo/doom.txt"
|
||||
intermissionmusic = "$MUSIC_INTER"
|
||||
intermissioncounter = true
|
||||
weaponslot = 1, "Bootspoon", "SuperBootspork"
|
||||
weaponslot = 2, "MiniZorcher"
|
||||
weaponslot = 3, "LargeZorcher", "SuperLargeZorcher"
|
||||
|
|
|
@ -25,6 +25,7 @@ gameinfo
|
|||
backpacktype = "Backpack"
|
||||
statusbar = "sbarinfo/doom.txt"
|
||||
intermissionmusic = "$MUSIC_DM2INT"
|
||||
intermissioncounter = true
|
||||
weaponslot = 1, "Fist", "Chainsaw"
|
||||
weaponslot = 2, "Pistol"
|
||||
weaponslot = 3, "Shotgun", "SuperShotgun"
|
||||
|
|
|
@ -25,6 +25,7 @@ gameinfo
|
|||
backpacktype = "BagOfHolding"
|
||||
statusbar = ""
|
||||
intermissionmusic = "mus_intr"
|
||||
intermissioncounter = false
|
||||
weaponslot = 1, "Staff", "Gauntlets"
|
||||
weaponslot = 2, "GoldWand"
|
||||
weaponslot = 3, "Crossbow"
|
||||
|
|
|
@ -28,6 +28,7 @@ gameinfo
|
|||
backpacktype = "BagOfHolding" // Hexen doesn't have a backpack so use Heretic's.
|
||||
statusbar = ""
|
||||
intermissionmusic = "hub"
|
||||
intermissioncounter = false
|
||||
weaponslot = 1, "FWeapFist", "CWeapMace", "MWeapWand"
|
||||
weaponslot = 2, "FWeapAxe", "CWeapStaff", "MWeapFrost"
|
||||
weaponslot = 3, "FWeapHammer", "CWeapFlame", "MWeapLightning"
|
||||
|
|
|
@ -25,6 +25,7 @@ gameinfo
|
|||
backpacktype = "AmmoSatchel"
|
||||
statusbar = ""
|
||||
intermissionmusic = "d_slide"
|
||||
intermissioncounter = false
|
||||
weaponslot = 1, "PunchDagger"
|
||||
weaponslot = 2, "StrifeCrossbow2", "StrifeCrossbow"
|
||||
weaponslot = 3, "AssaultGun"
|
||||
|
|
790
zdoom.vcproj
790
zdoom.vcproj
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue