Update to ZDoom r1662:

- Added ML_BLOCKUSE line flag, accessible through UDMF and Line_SetBlocking.
- Fixed handling of embedded WADs.
- Added Gez's A_CheckCeiling submission.
- Fixed: AM_NewResolution crashed when called from outside a level.
- Added support for Quake PAK files.
- Improved warning messages for WAD files with incorrect marker usage.
- 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.
- fixed MustConfirm parsing in MAPINFO
- Made the counting of intermission stats in Doom a GAMEINFO option so that
  it can be activated in all games.


git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@324 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
Christoph Oelckers 2009-04-28 21:31:02 +00:00
parent 1bd5fff28e
commit 7aa21e7efc
37 changed files with 2747 additions and 1791 deletions

View file

@ -1,4 +1,31 @@
April 17, 2009
April 28, 2009 (Changes by Graf Zahl)
- Added ML_BLOCKUSE line flag, accessible through UDMF and Line_SetBlocking.
April 25, 2009 (Changes by Graf Zahl)
- Fixed handling of embedded WADs.
April 23, 2009 (Changes by Graf Zahl)
- Added Gez's A_CheckCeiling submission.
- Fixed: AM_NewResolution crashed when called from outside a level.
- Added support for Quake PAK files.
- Improved warning messages for WAD files with incorrect marker usage.
- 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

View file

@ -6729,6 +6729,46 @@
</File>
</Filter>
</Filter>
<Filter
Name="Resource Files"
>
<File
RelativePath=".\src\resourcefiles\file_7z.cpp"
>
</File>
<File
RelativePath=".\src\resourcefiles\file_grp.cpp"
>
</File>
<File
RelativePath=".\src\resourcefiles\file_lump.cpp"
>
</File>
<File
RelativePath=".\src\resourcefiles\file_pak.cpp"
>
</File>
<File
RelativePath=".\src\resourcefiles\file_rff.cpp"
>
</File>
<File
RelativePath=".\src\resourcefiles\file_wad.cpp"
>
</File>
<File
RelativePath=".\src\resourcefiles\file_zip.cpp"
>
</File>
<File
RelativePath=".\src\resourcefiles\resourcefile.cpp"
>
</File>
<File
RelativePath=".\src\resourcefiles\resourcefile.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>

View file

@ -33,7 +33,7 @@ set( MINOR_VERSIONS "50" "49" "48" "47" "46" "45" "44" "43" "42" "41"
"27" "26" "25" "24" "23" "22" "21" "20" "21" "19" "18" "17" "16"
"15" "14" "13" "12" "11" "10" "09" "08" "07" "06" "05" "04" "03"
"02" "01" "00" )
set( MAJOR_VERSIONS "22" "20" )
set( MAJOR_VERSIONS "24" "22" "20" )
set( FMOD_DIR_VERSIONS ${FMOD_DIR_VERSIONS} "../fmod" )
foreach( majver ${MAJOR_VERSIONS} )
foreach( minver ${MINOR_VERSIONS} )
@ -715,6 +715,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

View file

@ -914,6 +914,11 @@ void AM_maxOutWindowScale ()
void AM_NewResolution()
{
fixed_t oldmin = min_scale_mtof;
if ( oldmin == 0 )
{
return; // [SP] Not in a game, exit!
}
AM_calcMinMaxMtoF();
scale_mtof = Scale(scale_mtof, min_scale_mtof, oldmin);
scale_ftom = MapDiv(MAPUNIT, scale_mtof);

View file

@ -150,6 +150,7 @@ enum ELineFlags
ML_CHECKSWITCHRANGE = 0x00400000,
ML_FIRSTSIDEONLY = 0x00800000, // activated only when crossed from front side
ML_BLOCKPROJECTILE = 0x01000000,
ML_BLOCKUSE = 0x02000000, // blocks all use actions through this line
};

View file

@ -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;

View file

@ -184,18 +184,17 @@ void FMapInfoParser::ParseSkill ()
}
else if (sc.Compare("MustConfirm"))
{
skill.MustConfirm = true;
if (format_type == FMT_New)
{
if (CheckAssign())
{
sc.MustGetString();
skill.MustConfirm = true;
skill.MustConfirmText = sc.String;
}
}
else
{
skill.MustConfirm = true;
if (sc.CheckToken(TK_StringConst))
{
skill.MustConfirmText = sc.String;

View file

@ -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.

View file

@ -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;

View file

@ -412,5 +412,6 @@ xx(lightabsolute)
xx(nofakecontrast)
xx(smoothlighting)
xx(blockprojectiles)
xx(blockuse)
xx(Renderstyle)

View file

@ -2369,6 +2369,7 @@ FUNC(LS_Line_SetBlocking)
ML_BLOCKPROJECTILE,
ML_BLOCKEVERYTHING,
ML_RAILING,
ML_BLOCKUSE,
-1
};

View file

@ -3636,7 +3636,7 @@ bool P_UseTraverse(AActor *usething, fixed_t endx, fixed_t endy, bool &foundline
if (in->d.line->special == 0 || !(in->d.line->activation & (SPAC_Use|SPAC_UseThrough)))
{
blocked:
if (in->d.line->flags & ML_BLOCKEVERYTHING)
if (in->d.line->flags & (ML_BLOCKEVERYTHING|ML_BLOCKUSE))
{
open.range = 0;
}

View file

@ -72,6 +72,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);

View file

@ -633,6 +633,10 @@ struct UDMFParser
Flag(ld->flags, ML_BLOCKPROJECTILE, key);
break;
case NAME_blockuse:
Flag(ld->flags, ML_BLOCKUSE, key);
break;
default:
break;
}

View file

@ -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;
}
}
if (!strnicmp (name, "WATERMAP", 8))
return MAKEARGB (128,0,0x4f,0xa5);
}
return blend;
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

View file

@ -0,0 +1,353 @@
/*
** 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];
if (file->GetLength() >= 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;
}

View file

@ -0,0 +1,155 @@
/*
** 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];
if (file->GetLength() >= 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;
}

View file

@ -0,0 +1,101 @@
/*
** 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;
NumLumps = 1;
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;
}

View file

@ -0,0 +1,147 @@
/*
** file_pak.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"
//==========================================================================
//
//
//
//==========================================================================
struct dpackfile_t
{
char name[56];
int filepos, filelen;
} ;
struct dpackheader_t
{
int ident; // == IDPAKHEADER
int dirofs;
int dirlen;
} ;
//==========================================================================
//
// Wad file
//
//==========================================================================
class FPakFile : public FUncompressedFile
{
public:
FPakFile(const char * filename, FileReader *file);
bool Open();
};
//==========================================================================
//
// FWadFile::FWadFile
//
// Initializes a WAD file
//
//==========================================================================
FPakFile::FPakFile(const char *filename, FileReader *file) : FUncompressedFile(filename, file)
{
Lumps = NULL;
}
//==========================================================================
//
// Open it
//
//==========================================================================
bool FPakFile::Open()
{
dpackheader_t header;
Reader->Read(&header, sizeof(header));
NumLumps = LittleLong(header.dirlen) / sizeof(dpackfile_t);
header.dirofs = LittleLong(header.dirofs);
dpackfile_t *fileinfo = new dpackfile_t[NumLumps];
Reader->Seek (header.dirofs, SEEK_SET);
Reader->Read (fileinfo, NumLumps * sizeof(dpackfile_t));
Lumps = new FUncompressedLump[NumLumps];
Printf(", %d lumps\n", NumLumps);
for(DWORD i = 0; i < NumLumps; i++)
{
Lumps[i].LumpNameSetup(fileinfo[i].name);
Lumps[i].Owner = this;
Lumps[i].Position = LittleLong(fileinfo[i].filepos);
Lumps[i].LumpSize = LittleLong(fileinfo[i].filelen);
Lumps[i].CheckEmbedded();
}
delete [] fileinfo;
return true;
}
//==========================================================================
//
// File open
//
//==========================================================================
FResourceFile *CheckPak(const char *filename, FileReader *file)
{
char head[4];
if (file->GetLength() >= 12)
{
file->Seek(0, SEEK_SET);
file->Read(&head, 4);
file->Seek(0, SEEK_SET);
if (!memcmp(head, "PACK", 4))
{
FResourceFile *rf = new FPakFile(filename, file);
if (rf->Open()) return rf;
delete rf;
}
}
return NULL;
}

View file

@ -0,0 +1,254 @@
/*
** 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];
if (file->GetLength() >= 16)
{
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;
}

View file

@ -0,0 +1,345 @@
/*
** 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)
{
if (start != -1)
{
Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", startmarker, endmarker);
}
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
{
Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", endmarker, startmarker);
if (flathack)
{
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];
if (file->GetLength() >= 12)
{
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;
}

View file

@ -0,0 +1,410 @@
/*
** 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];
if (file->GetLength() >= sizeof(FZipLocalFileHeader))
{
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;
}

View 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 && RefCount >= 0)
{
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(FullName, ".wad");
if (c && strlen(c) == 4 && !strchr(FullName, '/'))
{
// 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;
}

View 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;
SBYTE 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

View file

@ -3,5 +3,5 @@
// This file was automatically generated by the
// updaterevision tool. Do not edit by hand.
#define ZD_SVN_REVISION_STRING "1552"
#define ZD_SVN_REVISION_NUMBER 1552
#define ZD_SVN_REVISION_STRING "1562"
#define ZD_SVN_REVISION_NUMBER 1562

View file

@ -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.

View file

@ -330,7 +330,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);

View file

@ -1965,6 +1965,25 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckFloor)
}
//===========================================================================
//
// A_CheckCeiling
// [GZ] Totally copied on A_CheckFloor, jumps if actor touches ceiling
//
//===========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckCeiling)
{
ACTION_PARAM_START(1);
ACTION_PARAM_STATE(jump, 0);
ACTION_SET_RESULT(false);
if (self->z+self->height >= self->ceilingz) // Height needs to be counted
{
ACTION_JUMP(jump);
}
}
//===========================================================================
//
// A_Stop

File diff suppressed because it is too large Load diff

View file

@ -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();
};

View file

@ -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);

View file

@ -196,6 +196,7 @@ ACTOR Actor native //: Thinker
action native A_KillChildren();
action native A_KillSiblings();
action native A_CheckFloor(state label);
action native A_CheckCeiling(state label);
action native A_PlayerSkinCheck(state label);
action native A_BasicAttack(int meleedamage, sound meleesound, class<actor> missiletype, float missileheight);
action native A_ThrowGrenade(class<Actor> itemtype, float zheight = 0, float xymom = 0, float zmom = 0, bool useammo = true);

View file

@ -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"

View file

@ -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"

View file

@ -25,6 +25,7 @@ gameinfo
backpacktype = "BagOfHolding"
statusbar = ""
intermissionmusic = "mus_intr"
intermissioncounter = false
weaponslot = 1, "Staff", "Gauntlets"
weaponslot = 2, "GoldWand"
weaponslot = 3, "Crossbow"

View file

@ -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"

View file

@ -25,6 +25,7 @@ gameinfo
backpacktype = "AmmoSatchel"
statusbar = ""
intermissionmusic = "d_slide"
intermissioncounter = false
weaponslot = 1, "PunchDagger"
weaponslot = 2, "StrifeCrossbow2", "StrifeCrossbow"
weaponslot = 3, "AssaultGun"