Commit 2a8461a4 authored by engineer_apple's avatar engineer_apple

- added WAD Archive Loader ( Quake2 (WAL2) and Halflife (WAL3) are supported )

- CFileList
added Offset Parameter to SFileListEntry and removed the private array from the archive loaders.
CFileList::addItem now uses automatic incremental id if id = 0


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3336 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 816d5655
......@@ -12,10 +12,10 @@ Changes in 1.7.1 (05.07.2010) TA
allow to disable the bump/parallax on the earth like in the room ( with transparency )
- added DDS Image files, DXT2, DXT3, DXT4, DXT5, based on code from nvidia and Randy Reddig
- added a Halflife 1 Model Loader. ( bases on code by Fabio Concas )
- added a Halflife 1 Model Loader. ( bases on code by Fabio Concas ) Halflife 1.1.0.8, Counter-Strike 1.6 working
-> Load all Textures ( can even optimize it to texture atlas ), all bone animation, all submodels.
-> But to make use of the values ( named animation, mouth animation ) the Interface for IAnimatedMeshSceneNode
has to be reonde. I don't want to blow up the Interface again...
has to be redone. I don't want to blow up the Interface again...
TODO:
->can handle float frames numbers, the interface for getMesh should be reworked
......@@ -75,7 +75,10 @@ Changes in 1.7.1 (05.07.2010) TA
Valve uses WAL archive types like quake2. textures are inside model files
I reworked the existing ImageloaderWAL and added named Halflife textures to wal2 ( they have not extension )
and an LMP (palette/texture) loader into the same file ( all using 32bit now )
- added WAD Archive Loader ( Quake2 (WAL2) and Halflife (WAL3) are supported )
- CFileList
added Offset Parameter to SFileListEntry and removed the private array from the archive loaders.
CFileList::addItem now uses automatic incremental id if id = 0
- coreutil.h
added void splitFilenam, splits a path into components
- irstring.h
......
......@@ -38,7 +38,7 @@ int main()
if (driverType==video::EDT_COUNT)
return 1;
*/
video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9; // video::EDT_BURNINGSVIDEO; // video::EDT_OPENGL; //video::EDT_BURNINGSVIDEO;
video::E_DRIVER_TYPE driverType = video::EDT_BURNINGSVIDEO;// video::EDT_DIRECT3D9; // video::EDT_BURNINGSVIDEO; // video::EDT_OPENGL; //video::EDT_BURNINGSVIDEO;
bool shadows = true;
/*
......
......@@ -42,6 +42,9 @@ enum E_FILE_ARCHIVE_TYPE
//! A Tape ARchive
EFAT_TAR = MAKE_IRR_ID('T','A','R', 0),
//! A wad Archive, Quake2, Halflife
EFAT_WAD = MAKE_IRR_ID('W','A','D', 0),
//! The type of this archive is unknown
EFAT_UNKNOWN = MAKE_IRR_ID('u','n','k','n')
};
......
......@@ -42,6 +42,12 @@ public:
\return The size of the file in bytes. */
virtual u32 getFileSize(u32 index) const = 0;
//! Returns the file offset of a file in the file list, based on an index.
/** \param index is the zero based index of the file which should be returned.
The index must be less than the amount getFileCount() returns.
\return The size of the file in bytes. */
virtual u32 getFileOffset(u32 index) const = 0;
//! Returns the ID of a file in the file list, based on an index.
/** This optional ID can be used to link the file list entry to information held
elsewhere. For example this could be an index in an IFileArchive, linking the entry
......@@ -71,9 +77,10 @@ public:
//! Add as a file or folder to the list
/** \param fullPath The file name including path, from the root of the file list.
\param isDirectory True if this is a directory rather than a file.
\param offset, The file offset inside an archive
\param size The size of the file in bytes.
\param id The ID of the file in the archive which owns it */
virtual u32 addItem(const io::path& fullPath, u32 size, bool isDirectory, u32 id=0) = 0;
virtual u32 addItem(const io::path& fullPath, u32 offset, u32 size, bool isDirectory, u32 id=0) = 0;
//! Sorts the file list. You should call this after adding any items to the file list
virtual void sort() = 0;
......
......@@ -381,6 +381,8 @@ currently only supports zip archives, though. */
#define __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_
//! Define __IRR_COMPILE_WITH_TAR_ARCHIVE_LOADER_ if you want to open TAR archives
#define __IRR_COMPILE_WITH_TAR_ARCHIVE_LOADER_
//! Define __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_ if you want to open WAD archives
#define __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_
//! Set FPU settings
/** Irrlicht should use approximate float and integer fpu techniques
......
......@@ -60,11 +60,12 @@ const io::path& CFileList::getFullFileName(u32 index) const
}
//! adds a file or folder
u32 CFileList::addItem(const io::path& fullPath, u32 size, bool isDirectory, u32 id)
u32 CFileList::addItem(const io::path& fullPath, u32 offset, u32 size, bool isDirectory, u32 id)
{
SFileListEntry entry;
entry.ID = id ? id : Files.size();
entry.Offset = offset;
entry.Size = size;
entry.ID = id;
entry.Name = fullPath;
entry.Name.replace('\\', '/');
entry.IsDirectory = isDirectory;
......@@ -116,6 +117,12 @@ u32 CFileList::getFileSize(u32 index) const
return index < Files.size() ? Files[index].Size : 0;
}
//! Returns the size of a file
u32 CFileList::getFileOffset(u32 index) const
{
return index < Files.size() ? Files[index].Offset : 0;
}
//! Searches for a file or folder within the list, returns the index
s32 CFileList::findFile(const io::path& filename, bool isDirectory = false) const
......
......@@ -36,6 +36,9 @@ struct SFileListEntry
file in an archive, which can hold things like data offset and CRC. */
u32 ID;
//! FileOffset inside an archive
u32 Offset;
//! True if this is a folder, false if not.
bool IsDirectory;
......@@ -76,9 +79,10 @@ public:
//! Add as a file or folder to the list
/** \param fullPath The file name including path, up to the root of the file list.
\param isDirectory True if this is a directory rather than a file.
\param offset The offset where the file is stored in an archive
\param size The size of the file in bytes.
\param id The ID of the file in the archive which owns it */
virtual u32 addItem(const io::path& fullPath, u32 size, bool isDirectory, u32 id=0);
virtual u32 addItem(const io::path& fullPath, u32 offset, u32 size, bool isDirectory, u32 id=0);
//! Sorts the file list. You should call this after adding any items to the file list
virtual void sort();
......@@ -101,6 +105,9 @@ public:
//! Returns the size of a file
virtual u32 getFileSize(u32 index) const;
//! Returns the offest of a file
virtual u32 getFileOffset(u32 index) const;
//! Searches for a file or folder within the list, returns the index
virtual s32 findFile(const io::path& filename, bool isFolder) const;
......
......@@ -12,6 +12,7 @@
#include "CPakReader.h"
#include "CNPKReader.h"
#include "CTarReader.h"
#include "CWADReader.h"
#include "CFileList.h"
#include "CXMLReader.h"
#include "CXMLWriter.h"
......@@ -75,6 +76,11 @@ CFileSystem::CFileSystem()
#ifdef __IRR_COMPILE_WITH_TAR_ARCHIVE_LOADER_
ArchiveLoader.push_back(new CArchiveLoaderTAR(this));
#endif
#ifdef __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_
ArchiveLoader.push_back(new CArchiveLoaderWAD(this));
#endif
}
......@@ -699,7 +705,7 @@ IFileList* CFileSystem::createFileList()
{
if (core::isInSameDirectory(Path, merge->getFullFileName(j)) == 0)
{
r->addItem(merge->getFullFileName(j), merge->getFileSize(j), merge->isDirectory(j), 0);
r->addItem(merge->getFullFileName(j), merge->getFileOffset(j), merge->getFileSize(j), merge->isDirectory(j), 0);
}
}
}
......
......@@ -118,7 +118,7 @@ void CMountPointReader::buildDirectory()
if (!list->isDirectory(i))
{
addItem(full, list->getFileSize(i), false, RealFileNames.size());
addItem(full, list->getFileOffset(i), list->getFileSize(i), false, RealFileNames.size());
RealFileNames.push_back(list->getFullFileName(i));
}
else
......@@ -131,7 +131,7 @@ void CMountPointReader::buildDirectory()
if ( rel != "." && rel != ".." )
{
addItem(full, 0, true, 0);
addItem(full, 0, 0, true, 0);
Parent->changeWorkingDirectoryTo(pwd);
buildDirectory();
Parent->changeWorkingDirectoryTo("..");
......
......@@ -222,8 +222,7 @@ bool CNPKReader::scanLocalHeader()
#ifdef IRR_DEBUG_NPK_READER
os::Printer::log("Name", entry.Name);
#endif
addItem((isDir?dirName:dirName+entry.Name), entry.Length, isDir, Offsets.size());
Offsets.push_back(entry.Offset+header.Offset);
addItem((isDir?dirName:dirName+entry.Name), entry.Offset+header.Offset, entry.Length, isDir);
}
return true;
}
......@@ -244,12 +243,11 @@ IReadFile* CNPKReader::createAndOpenFile(const io::path& filename)
//! opens a file by index
IReadFile* CNPKReader::createAndOpenFile(u32 index)
{
if (index < Files.size())
{
return createLimitReadFile(Files[index].FullName, File, Offsets[Files[index].ID], Files[index].Size);
}
else
if (index >= Files.size() )
return 0;
const SFileListEntry &entry = Files[index];
return createLimitReadFile( entry.FullName, File, entry.Offset, entry.Size );
}
void CNPKReader::readString(core::stringc& name)
......
......@@ -117,9 +117,6 @@ namespace io
void readString(core::stringc& name);
IReadFile* File;
//! Contains offsets of the files from the start of the archive file
core::array<u32> Offsets;
};
} // end namespace io
......
......@@ -145,7 +145,6 @@ bool CPakReader::scanLocalHeader()
const int numberOfFiles = header.length / sizeof(SPAKFileEntry);
Offsets.reallocate(numberOfFiles);
// Loop through each entry in the table of contents
for(int i = 0; i < numberOfFiles; i++)
{
......@@ -162,8 +161,7 @@ bool CPakReader::scanLocalHeader()
entry.length = os::Byteswap::byteswap(entry.length);
#endif
addItem(io::path(entry.name), entry.length, false, Offsets.size());
Offsets.push_back(entry.offset);
addItem(io::path(entry.name), entry.offset, entry.length, false );
}
return true;
}
......@@ -184,12 +182,11 @@ IReadFile* CPakReader::createAndOpenFile(const io::path& filename)
//! opens a file by index
IReadFile* CPakReader::createAndOpenFile(u32 index)
{
if (index < Files.size())
{
return createLimitReadFile(Files[index].FullName, File, Offsets[Files[index].ID], Files[index].Size);
}
else
if (index >= Files.size() )
return 0;
const SFileListEntry &entry = Files[index];
return createLimitReadFile( entry.FullName, File, entry.Offset, entry.Size );
}
} // end namespace io
......
......@@ -114,8 +114,6 @@ namespace io
IReadFile* File;
//! Contains offsets of the files from the start of the archive file
core::array<u32> Offsets;
};
} // end namespace io
......
......@@ -385,6 +385,7 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters&
BurningShader[ETR_TEXTURE_GOURAUD_ALPHA_NOZ] = createTRTextureGouraudAlphaNoZ( this );
BurningShader[ETR_NORMAL_MAP_SOLID] = createTRNormalMap ( this );
BurningShader[ETR_STENCIL_SHADOW] = createTRStencilShadow ( this );
BurningShader[ETR_TEXTURE_BLEND] = createTRTextureBlend( this );
BurningShader[ETR_REFERENCE] = createTriangleRendererReference ( this );
......@@ -446,11 +447,12 @@ CBurningVideoDriver::~CBurningVideoDriver()
// delete triangle renderers
for (s32 i=0; i<ETR2_COUNT; ++i)
{
if (BurningShader[i])
BurningShader[i]->drop();
}
// delete zbuffer
// delete Additional buffer
if (StencilBuffer)
StencilBuffer->drop();
......@@ -1727,6 +1729,7 @@ void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vert
dc_area = screenarea2 ( face );
if ( Material.org.BackfaceCulling && F32_LOWER_EQUAL_0( dc_area ) )
continue;
else
if ( Material.org.FrontfaceCulling && F32_GREATER_EQUAL_0( dc_area ) )
continue;
......@@ -1844,6 +1847,7 @@ void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vert
dc_area = screenarea ( CurrentOut.data );
if ( Material.org.BackfaceCulling && F32_LOWER_EQUAL_0 ( dc_area ) )
continue;
else
if ( Material.org.FrontfaceCulling && F32_GREATER_EQUAL_0( dc_area ) )
continue;
......@@ -2547,6 +2551,41 @@ u32 CBurningVideoDriver::getMaximalPrimitiveCount() const
//! volume. Next use IVideoDriver::drawStencilShadow() to visualize the shadow.
void CBurningVideoDriver::drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail)
{
if (!StencilBuffer || !count)
return;
IBurningShader *shader = BurningShader [ ETR_STENCIL_SHADOW ];
shader->setRenderTarget(RenderTargetSurface, ViewPort);
//glStencilMask(~0);
//glStencilFunc(GL_ALWAYS, 0, ~0);
if (zfail)
{
Material.org.BackfaceCulling = false;
Material.org.FrontfaceCulling = true;
//glStencilOp(GL_KEEP, incr, GL_KEEP);
//glDrawArrays(GL_TRIANGLES,0,count);
Material.org.BackfaceCulling = true;
Material.org.FrontfaceCulling = false;
//glStencilOp(GL_KEEP, decr, GL_KEEP);
//glDrawArrays(GL_TRIANGLES,0,count);
}
else // zpass
{
Material.org.BackfaceCulling = true;
Material.org.FrontfaceCulling = false;
//glStencilOp(GL_KEEP, GL_KEEP, incr);
//glDrawArrays(GL_TRIANGLES,0,count);
Material.org.BackfaceCulling = false;
Material.org.FrontfaceCulling = true;
//glStencilOp(GL_KEEP, GL_KEEP, decr);
//glDrawArrays(GL_TRIANGLES,0,count);
}
#if 0
if (!StencilBuffer || !count)
return;
......
......@@ -78,19 +78,6 @@ namespace irr
namespace video
{
#define iter1(N) trial = root + (1 << (N)); if (n >= trial << (N)) { n -= trial << (N); root |= 2 << (N); }
tFixPoint fixsqrt (tFixPoint n)
{
tFixPoint root = 0, trial;
iter1 (15); iter1 (14); iter1 (13); iter1 (12);
iter1 (11); iter1 (10); iter1 ( 9); iter1 ( 8);
iter1 ( 7); iter1 ( 6); iter1 ( 5); iter1 ( 4);
iter1 ( 3); iter1 ( 2); iter1 ( 1); iter1 ( 0);
return root >> 1;
}
class CTRNormalMap : public IBurningShader
{
......@@ -111,8 +98,6 @@ private:
};
#include <windows.h>
//! constructor
CTRNormalMap::CTRNormalMap(CBurningVideoDriver* driver)
: IBurningShader(driver)
......@@ -120,21 +105,6 @@ CTRNormalMap::CTRNormalMap(CBurningVideoDriver* driver)
#ifdef _DEBUG
setDebugName("CTRNormalMap");
#endif
/*
char buf[256];
f32 f = 0.f;
tFixPoint a;
tFixPoint b;
for ( u32 i = 0; i < 100000; ++i )
{
f += 0.5f;
f32 r = sqrtf ( f );
a = tofix ( f );
b = fixsqrt ( a );
sprintf ( buf, "%.7f %.7f %.7f %.7f\n", f, r, a / FIX_POINT_F32_MUL, b / FIX_POINT_F32_MUL );
OutputDebugStringA ( buf );
}
*/
}
......
This diff is collapsed.
......@@ -216,8 +216,7 @@ u32 CTarReader::populateFileList()
pos = offset + (size / 512) * 512 + ((size % 512) ? 512 : 0);
// add file to list
addItem(fullPath, size, false, Offsets.size());
Offsets.push_back(offset);
addItem(fullPath, offset, size, false );
}
else
{
......@@ -246,10 +245,11 @@ IReadFile* CTarReader::createAndOpenFile(const io::path& filename)
//! opens a file by index
IReadFile* CTarReader::createAndOpenFile(u32 index)
{
if (index < Files.size())
return createLimitReadFile(Files[index].FullName, File, Offsets[Files[index].ID], Files[index].Size);
else
if (index >= Files.size() )
return 0;
const SFileListEntry &entry = Files[index];
return createLimitReadFile( entry.FullName, File, entry.Offset, entry.Size );
}
} // end namespace io
......
......@@ -135,9 +135,6 @@ namespace io
u32 populateFileList();
IReadFile* File;
//! Contains offsets of the files from the start of the archive file
core::array<u32> Offsets;
};
} // end namespace io
......
// Copyright (C) 2002-2009 Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
// Code contributed by skreamz
#include "IrrCompileConfig.h"
#ifdef __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_
#include "CWADReader.h"
#include "os.h"
#include "coreutil.h"
namespace irr
{
namespace io
{
//! Constructor
CArchiveLoaderWAD::CArchiveLoaderWAD( io::IFileSystem* fs)
: FileSystem(fs)
{
#ifdef _DEBUG
setDebugName("CArchiveLoaderWAD");
#endif
}
//! returns true if the file maybe is able to be loaded by this class
bool CArchiveLoaderWAD::isALoadableFileFormat(const io::path& filename) const
{
return core::hasFileExtension ( filename, "wad" );
}
//! Creates an archive from the filename
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
IFileArchive* CArchiveLoaderWAD::createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const
{
IFileArchive *archive = 0;
io::IReadFile* file = FileSystem->createAndOpenFile(filename);
if (file)
{
archive = createArchive ( file, ignoreCase, ignorePaths );
file->drop ();
}
return archive;
}
//! creates/loads an archive from the file.
//! \return Pointer to the created archive. Returns 0 if loading failed.
IFileArchive* CArchiveLoaderWAD::createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const
{
IFileArchive *archive = 0;
if ( file )
{
file->seek ( 0 );
archive = new CWADReader(file, ignoreCase, ignorePaths);
}
return archive;
}
//! Check if the file might be loaded by this class
/** Check might look into the file.
\param file File handle to check.
\return True if file seems to be loadable. */
bool CArchiveLoaderWAD::isALoadableFileFormat(io::IReadFile* file) const
{
SWADFileHeader header;
memset(&header, 0, sizeof(header));
file->read( &header.tag, 4 );
return !strncmp ( header.tag, "WAD2", 4 ) || !strncmp ( header.tag, "WAD3", 4 );
}
//! Check to see if the loader can create archives of this type.
bool CArchiveLoaderWAD::isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const
{
return fileType == EFAT_WAD;
}
void createDir ( const c8 *full );
/*!
WAD Reader
*/
CWADReader::CWADReader(IReadFile* file, bool ignoreCase, bool ignorePaths)
: CFileList((file ? file->getFileName() : io::path("")), ignoreCase, ignorePaths), File(file)
{
#ifdef _DEBUG
setDebugName("CWADReader");
#endif
if (File)
{
File->grab();
Base = File->getFileName();
Base.replace ( '\\', '/' );
// scan local headers
scanLocalHeader();
sort();
}
#if 0
for ( u32 i = 0; i < FileList.size(); ++i )
{
SWADFileEntry &e = FileList[i];
char buf[128];
snprintf ( buf, 128, "c:\\h2\\%s", e.wadFileName.c_str() );
createDir ( buf );
FILE * f = fopen ( buf, "wb" );
if ( 0 == f )
continue;
u8 * mem = new u8 [ e.header.disksize ];
File->seek ( e.header.filepos );
File->read ( mem, e.header.disksize );
fwrite ( mem, e.header.disksize, 1, f );
delete [] mem;
fclose ( f );
}
#endif
}
CWADReader::~CWADReader()
{
if (File)
File->drop();
}
//! return the id of the file Archive
const io::path& CWADReader::getArchiveName () const
{
return Base;
}
const IFileList* CWADReader::getFileList() const
{
return this;
}
//! scans for a local header, returns false if there is no more local file header.
bool CWADReader::scanLocalHeader()
{
SWADFileEntryOriginal entry;
SWADFileEntry save;
memset(&Header, 0, sizeof(SWADFileHeader));
File->read(&Header, sizeof(SWADFileHeader));
if ( 0 == strncmp ( Header.tag, "WAD2", 4 ) )
WadType = WAD_FORMAT_QUAKE2;
else
if ( 0 == strncmp ( Header.tag, "WAD3", 4 ) )
WadType = WAD_FORMAT_HALFLIFE;
else
WadType = WAD_FORMAT_UNKNOWN;
if ( WadType == WAD_FORMAT_UNKNOWN )
return false;
#ifdef __BIG_ENDIAN__
header.numlumps = os::Byteswap::byteswap(header.numlumps);
header.infotableofs = os::Byteswap::byteswap(header.infotableofs);
#endif
File->seek ( Header.infotableofs );
c8 buf[16];
for ( u32 i = 0; i < Header.numlumps; ++i )
{
// read entry
File->read(&entry, sizeof ( SWADFileEntryOriginal ));
entry.name[ sizeof ( entry.name ) - 1 ] = 0;
save.header = entry;
save.wadFileName = "/";
save.wadFileName += entry.name;
if ( WadType == WAD_FORMAT_HALFLIFE )
{
// don't know about the types! i'm guessing
switch ( entry.type )
{
case WAD_TYP_MIPTEX_HALFLIFE:
save.wadFileName += ".wal2";
break;
default:
snprintf ( buf, 16, ".%02d", entry.type );
save.wadFileName += buf;
break;
}
}
else
if ( WadType == WAD_FORMAT_QUAKE2 )
{
switch ( entry.type )
{
case WAD_TYP_MIPTEX: save.wadFileName += ".miptex"; break;
case WAD_TYP_SOUND: save.wadFileName += ".sound"; break;
case WAD_TYP_PALETTE: save.wadFileName += ".palette"; break;
case WAD_TYP_QTEX: save.wadFileName += ".qtex"; break;
case WAD_TYP_QPIC: save.wadFileName += ".qpic"; break;
case WAD_TYP_FONT: save.wadFileName += ".font"; break;
default:
snprintf ( buf, 16, ".%02d", entry.type );
save.wadFileName += buf;
break;
}
}
// add file to list
addItem(save.wadFileName,save.header.filepos, save.header.disksize, false );
//FileInfo.push_back(save);
}
return true;
}
//! opens a file by file name
IReadFile* CWADReader::createAndOpenFile(const io::path& filename)
{
s32 index = findFile(filename, false);
if (index != -1)
return createAndOpenFile(index);
return 0;
}
//! opens a file by index
IReadFile* CWADReader::createAndOpenFile(u32 index)
{
if (index >= Files.size() )
return 0;
const SFileListEntry &entry = Files[index];
return createLimitReadFile( entry.FullName, File, entry.Offset, entry.Size );
}
} // end namespace io
} // end namespace irr
#endif // __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_
// Copyright (C) 2002-2009 Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_WAD_READER_H_INCLUDED__
#define __C_WAD_READER_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_
#include "IReferenceCounted.h"
#include "IReadFile.h"
#include "irrArray.h"
#include "irrString.h"
#include "IFileSystem.h"
#include "CFileList.h"
namespace irr
{
namespace io
{
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( push, packing )
# pragma pack( 1 )
# define PACK_STRUCT
#elif defined( __GNUC__ )
# define PACK_STRUCT __attribute__((packed))
#else
# error compiler not supported
#endif
enum eWADFileTypes
{
WAD_FORMAT_UNKNOWN = 0,
WAD_FORMAT_QUAKE2 = 1,
WAD_FORMAT_HALFLIFE = 2,
WAD_CMP_NONE = 0,
WAD_CMP_LZSS = 1,
WAD_TYP_NONE = 0,
WAD_TYP_LABEL = 1,
WAD_TYP_LUMPY = 64, // 64 + grab command number
WAD_TYP_PALETTE = 64,
WAD_TYP_QTEX = 65,
WAD_TYP_QPIC = 66,
WAD_TYP_SOUND = 67,
WAD_TYP_MIPTEX = 68,
WAD_TYP_MIPTEX_HALFLIFE = 67,
WAD_TYP_FONT = 70,
};
struct SWADFileHeader
{
c8 tag[4]; // type of WAD format WAD2 = quake2, WAD3 = halflife
u32 numlumps;
u32 infotableofs;
} PACK_STRUCT;
struct SWADFileEntryOriginal
{
u32 filepos;
u32 disksize;
u32 size; // uncompressed
u8 type;
u8 compression;
u8 pad[2];
u8 name[16]; // must be null terminated
} PACK_STRUCT;
// Default alignment
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( pop, packing )
#endif
#undef PACK_STRUCT
struct SWADFileEntry
{
io::path simpleFileName;
bool operator < (const SWADFileEntry& other) const
{
return simpleFileName < other.simpleFileName;
}
io::path wadFileName;
SWADFileEntryOriginal header;
};
//! Archiveloader capable of loading WAD Archives
class CArchiveLoaderWAD : public IArchiveLoader
{
public:
//! Constructor
CArchiveLoaderWAD(io::IFileSystem* fs);
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".zip")
virtual bool isALoadableFileFormat(const io::path& filename) const;
//! Check if the file might be loaded by this class
/** Check might look into the file.
\param file File handle to check.
\return True if file seems to be loadable. */
virtual bool isALoadableFileFormat(io::IReadFile* file) const;
//! Check to see if the loader can create archives of this type.
/** Check based on the archive type.
\param fileType The archive type to check.
\return True if the archile loader supports this type, false if not */
virtual bool isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const;
//! Creates an archive from the filename
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
virtual IFileArchive* createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const;
//! creates/loads an archive from the file.
//! \return Pointer to the created archive. Returns 0 if loading failed.
virtual io::IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const;
private:
io::IFileSystem* FileSystem;
};
//! reads from WAD
class CWADReader : public IFileArchive, virtual CFileList
{
public:
CWADReader(IReadFile* file, bool ignoreCase, bool ignorePaths);
virtual ~CWADReader();
// file archive methods
//! return the id of the file Archive
virtual const io::path& getArchiveName() const;
//! opens a file by file name
virtual IReadFile* createAndOpenFile(const io::path& filename);
//! opens a file by index
virtual IReadFile* createAndOpenFile(u32 index);
//! returns the list of files
virtual const IFileList* getFileList() const;
//! get the class Type
virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_WAD; }
private:
io::path Type;
//! scans for a local header, returns false if there is no more local file header.
bool scanLocalHeader();
//! splits filename from zip file into useful filenames and paths
void extractFilename(SWADFileEntry* entry);
io::path Base;
io::path MountPoint;
IReadFile* File;
eWADFileTypes WadType;
SWADFileHeader Header;
//core::array<SWADFileEntry> FileInfo;
io::IFileSystem* FileSystem;
};
} // end namespace io
} // end namespace irr
#endif
#endif // #ifdef __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_
......@@ -363,7 +363,7 @@ bool CZipReader::scanGZipHeader()
#endif
// now we've filled all the fields, this is just a standard deflate block
addItem(ZipFileName, entry.header.DataDescriptor.UncompressedSize, false, 0);
addItem(ZipFileName, entry.Offset, entry.header.DataDescriptor.UncompressedSize, false, 0);
FileInfo.push_back(entry);
}
......@@ -471,7 +471,7 @@ bool CZipReader::scanZipHeader()
//os::Debuginfo::print("added file from archive", ZipFileName.c_str());
#endif
addItem(ZipFileName, entry.header.DataDescriptor.UncompressedSize, false, FileInfo.size());
addItem(ZipFileName, entry.Offset, entry.header.DataDescriptor.UncompressedSize, false, FileInfo.size());
FileInfo.push_back(entry);
return true;
......
......@@ -112,6 +112,7 @@ namespace video
ETR_TEXTURE_GOURAUD_ALPHA_NOZ,
ETR_NORMAL_MAP_SOLID,
ETR_STENCIL_SHADOW,
ETR_TEXTURE_BLEND,
ETR_REFERENCE,
......@@ -187,6 +188,7 @@ namespace video
IBurningShader* createTRTextureInverseAlphaBlend(CBurningVideoDriver* driver);
IBurningShader* createTRNormalMap(CBurningVideoDriver* driver);
IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererReference(CBurningVideoDriver* driver);
......
......@@ -2531,6 +2531,10 @@
RelativePath=".\CTRNormalMap.cpp"
>
</File>
<File
RelativePath=".\CTRStencilShadow.cpp"
>
</File>
<File
RelativePath="CTRTextureBlend.cpp"
>
......@@ -3316,6 +3320,14 @@
RelativePath="CTarReader.h"
>
</File>
<File
RelativePath=".\CWADReader.cpp"
>
</File>
<File
RelativePath=".\CWADReader.h"
>
</File>
<File
RelativePath="CWriteFile.cpp"
>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment