- 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
master
engineer_apple 2010-07-07 20:27:10 +00:00
parent 816d5655fc
commit 2a8461a4fe
23 changed files with 1336 additions and 73 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,767 @@
// Copyright (C) 2002-2009 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef USE_SBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
#undef IPOL_T2
#undef IPOL_L0
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define USE_SBUFFER
#define IPOL_W
#define CMP_W
//#define WRITE_W
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRStencilShadow : public IBurningShader
{
public:
//! constructor
CTRStencilShadow(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
private:
void scanline ();
sScanConvertData scan;
sScanLineData line;
};
//! constructor
CTRStencilShadow::CTRStencilShadow(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRStencilShadow");
#endif
}
/*!
*/
void CTRStencilShadow::scanline ()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
#ifdef USE_SBUFFER
u32 *stencil;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC[MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
#ifdef IPOL_L0
sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef IPOL_T2
slopeT[2] = (line.t[2][1] - line.t[2][0]) * invDeltaX;
#endif
#ifdef IPOL_L0
slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC[0] * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#ifdef IPOL_T2
line.t[2][0] += slopeT[2] * subPixel;
#endif
#ifdef IPOL_L0
line.l[0][0] += slopeL[0] * subPixel;
#endif
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef USE_SBUFFER
stencil = (u32*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef INVERSE_W
f32 inversew;
#endif
#ifdef IPOL_C0
tFixPoint r3, g3, b3;
#endif
for ( s32 i = 0; i <= dx; i++ )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] >= z[i] )
#endif
{
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
#else
#endif
dst[i] = 0xFFFFFFFF;
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC[0];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
#ifdef IPOL_T2
line.t[2][0] += slopeT[2];
#endif
#ifdef IPOL_L0
line.l[0][0] += slopeL[0];
#endif
}
}
void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
#ifdef IPOL_T2
scan.slopeT[2][0] = (c->Tex[2] - a->Tex[2]) * scan.invDeltaY[0];
scan.t[2][0] = a->Tex[2];
#endif
#ifdef IPOL_L0
scan.slopeL[0][0] = (c->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[0];
scan.l[0][0] = a->LightTangent[0];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
//if ( (f32) 0.0 != scan.invDeltaY[1] )
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
#ifdef IPOL_T2
scan.slopeT[2][1] = (b->Tex[2] - a->Tex[2]) * scan.invDeltaY[1];
scan.t[2][1] = a->Tex[2];
#endif
#ifdef IPOL_L0
scan.slopeL[0][1] = (b->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[1];
scan.l[0][1] = a->LightTangent[0];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#ifdef IPOL_T2
scan.t[2][0] += scan.slopeT[2][0] * subPixel;
scan.t[2][1] += scan.slopeT[2][1] * subPixel;
#endif
#ifdef IPOL_L0
scan.l[0][0] += scan.slopeL[0][0] * subPixel;
scan.l[0][1] += scan.slopeL[0][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
#ifdef IPOL_T2
line.t[2][scan.left] = scan.t[2][0];
line.t[2][scan.right] = scan.t[2][1];
#endif
#ifdef IPOL_L0
line.l[0][scan.left] = scan.l[0][0];
line.l[0][scan.right] = scan.l[0][1];
#endif
// render a scanline
scanline ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
#ifdef IPOL_T2
scan.t[2][0] += scan.slopeT[2][0];
scan.t[2][1] += scan.slopeT[2][1];
#endif
#ifdef IPOL_L0
scan.l[0][0] += scan.slopeL[0][0];
scan.l[0][1] += scan.slopeL[0][1];
#endif
}
}
// rasterize lower sub-triangle
//if ( (f32) 0.0 != scan.invDeltaY[2] )
if ( F32_GREATER_0 ( scan.invDeltaY[2] ) )
{
// advance to middle point
//if( (f32) 0.0 != scan.invDeltaY[1] )
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
#ifdef IPOL_T2
scan.t[2][0] = a->Tex[2] + scan.slopeT[2][0] * temp[0];
#endif
#ifdef IPOL_L0
scan.l[0][0] = a->LightTangent[0] + scan.slopeL[0][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
#ifdef IPOL_T2
scan.slopeT[2][1] = (c->Tex[2] - b->Tex[2]) * scan.invDeltaY[2];
scan.t[2][1] = b->Tex[2];
#endif
#ifdef IPOL_L0
scan.slopeL[0][1] = (c->LightTangent[0] - b->LightTangent[0]) * scan.invDeltaY[2];
scan.l[0][1] = b->LightTangent[0];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#ifdef IPOL_T2
scan.t[2][0] += scan.slopeT[2][0] * subPixel;
scan.t[2][1] += scan.slopeT[2][1] * subPixel;
#endif
#ifdef IPOL_L0
scan.l[0][0] += scan.slopeL[0][0] * subPixel;
scan.l[0][1] += scan.slopeL[0][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
#ifdef IPOL_T2
line.t[2][scan.left] = scan.t[2][0];
line.t[2][scan.right] = scan.t[2][1];
#endif
#ifdef IPOL_L0
line.l[0][scan.left] = scan.l[0][0];
line.l[0][scan.right] = scan.l[0][1];
#endif
// render a scanline
scanline ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
#ifdef IPOL_T2
scan.t[2][0] += scan.slopeT[2][0];
scan.t[2][1] += scan.slopeT[2][1];
#endif
#ifdef IPOL_L0
scan.l[0][0] += scan.slopeL[0][0];
scan.l[0][1] += scan.slopeL[0][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a triangle renderer
IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRStencilShadow(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

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

View File

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

View File

@ -0,0 +1,263 @@
// 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_

View File

@ -0,0 +1,188 @@
// 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_

View File

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

View File

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

View File

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