mirror of
https://github.com/leozide/leocad
synced 2025-01-17 18:11:42 +01:00
New Pieces Library code.
This commit is contained in:
parent
b5a940aca9
commit
71f27a45c2
9 changed files with 848 additions and 259 deletions
|
@ -208,7 +208,7 @@ void ObjArray<T>::Expand(int Grow)
|
||||||
{
|
{
|
||||||
if ((m_Length + Grow) > m_Alloc)
|
if ((m_Length + Grow) > m_Alloc)
|
||||||
{
|
{
|
||||||
int NewSize = ((m_Length + Grow) / m_Grow + 1) * m_Grow;
|
int NewSize = ((m_Length + Grow + m_Grow - 1) / m_Grow) * m_Grow;
|
||||||
|
|
||||||
T* NewData = new T[NewSize];
|
T* NewData = new T[NewSize];
|
||||||
|
|
||||||
|
@ -252,6 +252,13 @@ void ObjArray<T>::Add(const T& Obj)
|
||||||
m_Data[m_Length++] = Obj;
|
m_Data[m_Length++] = Obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T& ObjArray<T>::Add()
|
||||||
|
{
|
||||||
|
Expand(1);
|
||||||
|
return m_Data[m_Length++];
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void ObjArray<T>::AddSorted (const T& Obj, LC_OBJARRAY_COMPARE_FUNC Func, void* SortData)
|
void ObjArray<T>::AddSorted (const T& Obj, LC_OBJARRAY_COMPARE_FUNC Func, void* SortData)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,6 +13,7 @@ public:
|
||||||
int GetSize() const
|
int GetSize() const
|
||||||
{ return m_nLength; }
|
{ return m_nLength; }
|
||||||
void SetSize(int Size);
|
void SetSize(int Size);
|
||||||
|
void Expand(int nGrow);
|
||||||
|
|
||||||
T* RemoveIndex(int nIndex);
|
T* RemoveIndex(int nIndex);
|
||||||
T* RemovePointer(T* pObj);
|
T* RemovePointer(T* pObj);
|
||||||
|
@ -30,8 +31,6 @@ public:
|
||||||
{ return m_pData[nIndex]; }
|
{ return m_pData[nIndex]; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void Expand(int nGrow);
|
|
||||||
|
|
||||||
T** m_pData;
|
T** m_pData;
|
||||||
int m_nLength;
|
int m_nLength;
|
||||||
int m_nAlloc;
|
int m_nAlloc;
|
||||||
|
@ -52,7 +51,9 @@ public:
|
||||||
void RemoveIndex(int Index);
|
void RemoveIndex(int Index);
|
||||||
void RemoveAll();
|
void RemoveAll();
|
||||||
void SetSize(int NewSize);
|
void SetSize(int NewSize);
|
||||||
|
void Expand(int Grow);
|
||||||
void Add(const T& Obj);
|
void Add(const T& Obj);
|
||||||
|
T& Add();
|
||||||
void AddSorted(const T& Obj, LC_OBJARRAY_COMPARE_FUNC Func, void* SortData);
|
void AddSorted(const T& Obj, LC_OBJARRAY_COMPARE_FUNC Func, void* SortData);
|
||||||
void InsertAt(int Index, const T& Obj);
|
void InsertAt(int Index, const T& Obj);
|
||||||
|
|
||||||
|
@ -60,8 +61,6 @@ public:
|
||||||
{ return m_Data[Index]; }
|
{ return m_Data[Index]; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void Expand(int Grow);
|
|
||||||
|
|
||||||
T* m_Data;
|
T* m_Data;
|
||||||
int m_Length;
|
int m_Length;
|
||||||
int m_Alloc;
|
int m_Alloc;
|
||||||
|
|
|
@ -1,15 +1,581 @@
|
||||||
#include "lc_global.h"
|
#include "lc_global.h"
|
||||||
#include "lc_library.h"
|
#include "lc_library.h"
|
||||||
|
#include "lc_zipfile.h"
|
||||||
|
#include "lc_file.h"
|
||||||
|
#include "pieceinf.h"
|
||||||
|
#include "lc_colors.h"
|
||||||
|
|
||||||
lcPiecesLibrary::lcPiecesLibrary()
|
lcPiecesLibrary::lcPiecesLibrary()
|
||||||
{
|
{
|
||||||
|
mZipFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
lcPiecesLibrary::~lcPiecesLibrary()
|
lcPiecesLibrary::~lcPiecesLibrary()
|
||||||
{
|
{
|
||||||
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
||||||
|
delete mPieces[PieceIdx];
|
||||||
|
|
||||||
|
delete mZipFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lcPiecesLibrary::OpenArchive(const char* LibPath)
|
bool lcPiecesLibrary::OpenArchive(const char* FileName)
|
||||||
{
|
{
|
||||||
|
mZipFile = new lcZipFile();
|
||||||
|
|
||||||
|
if (!mZipFile->Open(FileName))
|
||||||
|
{
|
||||||
|
delete mZipFile;
|
||||||
|
mZipFile = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int FileIdx = 0; FileIdx < mZipFile->mFiles.GetSize(); FileIdx++)
|
||||||
|
{
|
||||||
|
lcZipFileInfo& FileInfo = mZipFile->mFiles[FileIdx];
|
||||||
|
char Name[LC_PIECE_NAME_LEN];
|
||||||
|
|
||||||
|
const char* Src = FileInfo.file_name;
|
||||||
|
char* Dst = Name;
|
||||||
|
|
||||||
|
while (*Src && Dst - Name < LC_PIECE_NAME_LEN)
|
||||||
|
{
|
||||||
|
if (*Src >= 'a' && *Src <= 'z')
|
||||||
|
*Dst = *Src + 'A' - 'a';
|
||||||
|
else if (*Src == '\\')
|
||||||
|
*Dst = '/';
|
||||||
|
else
|
||||||
|
*Dst = *Src;
|
||||||
|
|
||||||
|
Src++;
|
||||||
|
Dst++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Dst - Name <= 4)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Dst -= 4;
|
||||||
|
if (memcmp(Dst, ".DAT", 4))
|
||||||
|
continue;
|
||||||
|
*Dst = 0;
|
||||||
|
|
||||||
|
if (memcmp(Name, "LDRAW/", 6))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!memcmp(Name + 6, "PARTS/", 6))
|
||||||
|
{
|
||||||
|
if (memcmp(Name + 12, "S/", 2))
|
||||||
|
{
|
||||||
|
PieceInfo* Info = new PieceInfo();
|
||||||
|
mPieces.Add(Info);
|
||||||
|
|
||||||
|
strncpy(Info->m_strName, Name + 12, sizeof(Info->m_strName));
|
||||||
|
Info->m_strName[sizeof(Info->m_strName) - 1] = 0;
|
||||||
|
|
||||||
|
Info->m_nFlags = 0;
|
||||||
|
Info->m_nOffset = FileIdx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lcLibraryPrimitive* Prim = new lcLibraryPrimitive();
|
||||||
|
mPrimitives.Add(Prim);
|
||||||
|
strncpy(Prim->mName, Name + 12, sizeof(Prim->mName));
|
||||||
|
Prim->mName[sizeof(Prim->mName) - 1] = 0;
|
||||||
|
Prim->mZipFileIndex = FileIdx;
|
||||||
|
Prim->mLoaded = false;
|
||||||
|
Prim->mStud = false;
|
||||||
|
Prim->mSubFile = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!memcmp(Name + 6, "P/", 2))
|
||||||
|
{
|
||||||
|
lcLibraryPrimitive* Prim = new lcLibraryPrimitive();
|
||||||
|
mPrimitives.Add(Prim);
|
||||||
|
strncpy(Prim->mName, Name + 8, sizeof(Prim->mName));
|
||||||
|
Prim->mName[sizeof(Prim->mName) - 1] = 0;
|
||||||
|
Prim->mZipFileIndex = FileIdx;
|
||||||
|
Prim->mLoaded = false;
|
||||||
|
Prim->mStud = (memcmp(Prim->mName, "STU", 3) == 0);
|
||||||
|
Prim->mSubFile = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lcMemFile PieceFile;
|
||||||
|
|
||||||
|
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
|
||||||
|
{
|
||||||
|
PieceInfo* Info = mPieces[PieceInfoIndex];
|
||||||
|
|
||||||
|
mZipFile->ExtractFile(Info->m_nOffset, PieceFile, 256);
|
||||||
|
PieceFile.Seek(0, SEEK_END);
|
||||||
|
PieceFile.WriteU8(0);
|
||||||
|
|
||||||
|
char* Src = (char*)PieceFile.mBuffer + 2;
|
||||||
|
char* Dst = Info->m_strDescription;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (*Src != '\r' && *Src != '\n' && *Src && Dst - Info->m_strDescription < sizeof(Info->m_strDescription) - 1)
|
||||||
|
{
|
||||||
|
*Dst++ = *Src++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*Dst = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool lcPiecesLibrary::LoadPiece(const char* PieceName)
|
||||||
|
{
|
||||||
|
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
|
||||||
|
{
|
||||||
|
PieceInfo* Info = mPieces[PieceInfoIndex];
|
||||||
|
|
||||||
|
if (!strcmp(Info->m_strName, PieceName))
|
||||||
|
return LoadPiece(PieceInfoIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool lcPiecesLibrary::LoadPiece(int PieceIndex)
|
||||||
|
{
|
||||||
|
PieceInfo* Info = mPieces[PieceIndex];
|
||||||
|
lcMemFile PieceFile;
|
||||||
|
lcLibraryMeshData MeshData;
|
||||||
|
|
||||||
|
if (!mZipFile->ExtractFile(Info->m_nOffset, PieceFile))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!ReadMeshData(PieceFile, lcMatrix44Identity(), 16, MeshData))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
lcMesh* Mesh = new lcMesh();
|
||||||
|
|
||||||
|
int NumIndices = 0;
|
||||||
|
|
||||||
|
for (int SectionIdx = 0; SectionIdx < MeshData.mSections.GetSize(); SectionIdx++)
|
||||||
|
NumIndices += MeshData.mSections[SectionIdx]->mIndices.GetSize();
|
||||||
|
|
||||||
|
Mesh->Create(MeshData.mSections.GetSize(), MeshData.mVertices.GetSize(), NumIndices);
|
||||||
|
|
||||||
|
lcVector3* DstVerts = (lcVector3*)Mesh->mVertexBuffer.mData;
|
||||||
|
lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||||
|
|
||||||
|
for (int VertexIdx = 0; VertexIdx < MeshData.mVertices.GetSize(); VertexIdx++)
|
||||||
|
{
|
||||||
|
const lcVector3& SrcVertex = MeshData.mVertices[VertexIdx];
|
||||||
|
lcVector3& Vertex = *DstVerts++;
|
||||||
|
Vertex = lcVector3(SrcVertex.x / 25.0f, SrcVertex.z / 25.0f, -SrcVertex.y / 25.0f);
|
||||||
|
|
||||||
|
Min.x = lcMin(Min.x, Vertex.x);
|
||||||
|
Min.y = lcMin(Min.y, Vertex.y);
|
||||||
|
Min.z = lcMin(Min.z, Vertex.z);
|
||||||
|
Max.x = lcMax(Max.x, Vertex.x);
|
||||||
|
Max.y = lcMax(Max.y, Vertex.y);
|
||||||
|
Max.z = lcMax(Max.z, Vertex.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
Info->m_fDimensions[0] = Max.x;
|
||||||
|
Info->m_fDimensions[1] = Max.y;
|
||||||
|
Info->m_fDimensions[2] = Max.z;
|
||||||
|
Info->m_fDimensions[3] = Min.x;
|
||||||
|
Info->m_fDimensions[4] = Min.y;
|
||||||
|
Info->m_fDimensions[5] = Min.z;
|
||||||
|
|
||||||
|
NumIndices = 0;
|
||||||
|
|
||||||
|
for (int SectionIdx = 0; SectionIdx < MeshData.mSections.GetSize(); SectionIdx++)
|
||||||
|
{
|
||||||
|
lcMeshSection& DstSection = Mesh->mSections[SectionIdx];
|
||||||
|
lcLibraryMeshSection* SrcSection = MeshData.mSections[SectionIdx];
|
||||||
|
|
||||||
|
DstSection.ColorIndex = lcGetColorIndex(SrcSection->mColorCode);
|
||||||
|
DstSection.PrimitiveType = SrcSection->mTriangles ? GL_TRIANGLES : GL_LINES;
|
||||||
|
DstSection.NumIndices = SrcSection->mIndices.GetSize();
|
||||||
|
|
||||||
|
if (Mesh->mNumVertices < 0x10000)
|
||||||
|
{
|
||||||
|
DstSection.IndexOffset = NumIndices * 2;
|
||||||
|
|
||||||
|
lcuint16* Index = (lcuint16*)Mesh->mIndexBuffer.mData + NumIndices;
|
||||||
|
|
||||||
|
for (int IndexIdx = 0; IndexIdx < DstSection.NumIndices; IndexIdx++)
|
||||||
|
*Index++ = SrcSection->mIndices[IndexIdx];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DstSection.IndexOffset = NumIndices * 4;
|
||||||
|
|
||||||
|
lcuint32* Index = (lcuint32*)Mesh->mIndexBuffer.mData + NumIndices;
|
||||||
|
|
||||||
|
for (int IndexIdx = 0; IndexIdx < DstSection.NumIndices; IndexIdx++)
|
||||||
|
*Index++ = SrcSection->mIndices[IndexIdx];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SrcSection->mTriangles)
|
||||||
|
{
|
||||||
|
if (SrcSection->mColorCode == 16)
|
||||||
|
Info->m_nFlags |= LC_PIECE_HAS_DEFAULT;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (lcIsColorTranslucent(DstSection.ColorIndex))
|
||||||
|
Info->m_nFlags |= LC_PIECE_HAS_TRANSLUCENT;
|
||||||
|
else
|
||||||
|
Info->m_nFlags |= LC_PIECE_HAS_SOLID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Info->m_nFlags |= LC_PIECE_HAS_LINES;
|
||||||
|
|
||||||
|
NumIndices += DstSection.NumIndices;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mesh->UpdateBuffers();
|
||||||
|
Info->mMesh = Mesh;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcPiecesLibrary::FindPrimitiveIndex(const char* Name)
|
||||||
|
{
|
||||||
|
for (int PrimitiveIndex = 0; PrimitiveIndex < mPrimitives.GetSize(); PrimitiveIndex++)
|
||||||
|
if (!strcmp(mPrimitives[PrimitiveIndex]->mName, Name))
|
||||||
|
return PrimitiveIndex;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
|
||||||
|
{
|
||||||
|
lcLibraryPrimitive* Primitive = mPrimitives[PrimitiveIndex];
|
||||||
|
lcMemFile File;
|
||||||
|
|
||||||
|
if (!mZipFile->ExtractFile(Primitive->mZipFileIndex, File))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!ReadMeshData(File, lcMatrix44Identity(), 16, Primitive->mMeshData))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Primitive->mLoaded = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcLibraryMeshData& MeshData)
|
||||||
|
{
|
||||||
|
char Line[1024];
|
||||||
|
|
||||||
|
while (File.ReadLine(Line, sizeof(Line)))
|
||||||
|
{
|
||||||
|
lcuint32 ColorCode, ColorCodeHex;
|
||||||
|
int LineType;
|
||||||
|
|
||||||
|
if (sscanf(Line, "%d", &LineType) != 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (LineType < 1 || LineType > 4)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (sscanf(Line, "%d %d", &LineType, &ColorCode) != 2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ColorCode == 0)
|
||||||
|
{
|
||||||
|
sscanf(Line, "%d %i", &LineType, &ColorCodeHex);
|
||||||
|
|
||||||
|
if (ColorCode != ColorCodeHex)
|
||||||
|
ColorCode = ColorCodeHex | LC_COLOR_DIRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ColorCode == 16)
|
||||||
|
ColorCode = CurrentColorCode;
|
||||||
|
|
||||||
|
int Dummy;
|
||||||
|
lcVector3 Points[4];
|
||||||
|
|
||||||
|
switch (LineType)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
char FileName[LC_MAXPATH];
|
||||||
|
float fm[12];
|
||||||
|
|
||||||
|
sscanf(Line, "%d %i %f %f %f %f %f %f %f %f %f %f %f %f %s", &LineType, &Dummy, &fm[0], &fm[1], &fm[2], &fm[3], &fm[4], &fm[5], &fm[6], &fm[7], &fm[8], &fm[9], &fm[10], &fm[11], FileName);
|
||||||
|
|
||||||
|
char* Ch;
|
||||||
|
for (Ch = FileName; *Ch; Ch++)
|
||||||
|
{
|
||||||
|
if (*Ch >= 'a' && *Ch <= 'z')
|
||||||
|
*Ch = *Ch + 'A' - 'a';
|
||||||
|
else if (*Ch == '\\')
|
||||||
|
*Ch = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Ch - FileName > 4)
|
||||||
|
{
|
||||||
|
Ch -= 4;
|
||||||
|
if (!memcmp(Ch, ".DAT", 4))
|
||||||
|
*Ch = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PrimitiveIndex = FindPrimitiveIndex(FileName);
|
||||||
|
lcMatrix44 IncludeTransform(lcVector4(fm[3], fm[6], fm[9], 0.0f), lcVector4(fm[4], fm[7], fm[10], 0.0f), lcVector4(fm[5], fm[8], fm[11], 0.0f), lcVector4(fm[0], fm[1], fm[2], 1.0f));
|
||||||
|
IncludeTransform = lcMul(IncludeTransform, CurrentTransform);
|
||||||
|
|
||||||
|
if (PrimitiveIndex != -1)
|
||||||
|
{
|
||||||
|
lcLibraryPrimitive* Primitive = mPrimitives[PrimitiveIndex];
|
||||||
|
|
||||||
|
if (!Primitive->mLoaded && !LoadPrimitive(PrimitiveIndex))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (Primitive->mStud)
|
||||||
|
MeshData.AddMeshDataNoDuplicateCheck(Primitive->mMeshData, IncludeTransform, ColorCode);
|
||||||
|
else if (!Primitive->mSubFile)
|
||||||
|
MeshData.AddMeshData(Primitive->mMeshData, IncludeTransform, ColorCode);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lcMemFile IncludeFile;
|
||||||
|
|
||||||
|
if (!mZipFile->ExtractFile(Primitive->mZipFileIndex, IncludeFile))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, MeshData))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
|
||||||
|
{
|
||||||
|
PieceInfo* Info = mPieces[PieceInfoIndex];
|
||||||
|
|
||||||
|
if (strcmp(Info->m_strName, FileName))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
lcMemFile IncludeFile;
|
||||||
|
|
||||||
|
if (!mZipFile->ExtractFile(Info->m_nOffset, IncludeFile))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, MeshData))
|
||||||
|
break;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
sscanf(Line, "%d %i %f %f %f %f %f %f", &LineType, &Dummy, &Points[0].x, &Points[0].y, &Points[0].z, &Points[1].x, &Points[1].y, &Points[1].z);
|
||||||
|
|
||||||
|
Points[0] = lcMul31(Points[0], CurrentTransform);
|
||||||
|
Points[1] = lcMul31(Points[1], CurrentTransform);
|
||||||
|
|
||||||
|
MeshData.AddLine(LineType, ColorCode, Points);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
sscanf(Line, "%d %i %f %f %f %f %f %f %f %f %f", &LineType, &Dummy, &Points[0].x, &Points[0].y, &Points[0].z,
|
||||||
|
&Points[1].x, &Points[1].y, &Points[1].z, &Points[2].x, &Points[2].y, &Points[2].z);
|
||||||
|
|
||||||
|
Points[0] = lcMul31(Points[0], CurrentTransform);
|
||||||
|
Points[1] = lcMul31(Points[1], CurrentTransform);
|
||||||
|
Points[2] = lcMul31(Points[2], CurrentTransform);
|
||||||
|
|
||||||
|
MeshData.AddLine(LineType, ColorCode, Points);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
sscanf(Line, "%d %i %f %f %f %f %f %f %f %f %f %f %f %f", &LineType, &Dummy, &Points[0].x, &Points[0].y, &Points[0].z,
|
||||||
|
&Points[1].x, &Points[1].y, &Points[1].z, &Points[2].x, &Points[2].y, &Points[2].z, &Points[3].x, &Points[3].y, &Points[3].z);
|
||||||
|
|
||||||
|
Points[0] = lcMul31(Points[0], CurrentTransform);
|
||||||
|
Points[1] = lcMul31(Points[1], CurrentTransform);
|
||||||
|
Points[2] = lcMul31(Points[2], CurrentTransform);
|
||||||
|
Points[3] = lcMul31(Points[3], CurrentTransform);
|
||||||
|
|
||||||
|
MeshData.AddLine(LineType, ColorCode, Points);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcLibraryMeshData::AddLine(int LineType, lcuint32 ColorCode, const lcVector3* Vertices)
|
||||||
|
{
|
||||||
|
lcLibraryMeshSection* Section;
|
||||||
|
int SectionIdx;
|
||||||
|
bool Triangles = (LineType != 2);
|
||||||
|
|
||||||
|
for (SectionIdx = 0; SectionIdx < mSections.GetSize(); SectionIdx++)
|
||||||
|
{
|
||||||
|
Section = mSections[SectionIdx];
|
||||||
|
|
||||||
|
if (Section->mColorCode == ColorCode && Section->mTriangles == Triangles)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SectionIdx == mSections.GetSize())
|
||||||
|
{
|
||||||
|
Section = new lcLibraryMeshSection;
|
||||||
|
|
||||||
|
Section->mColorCode = ColorCode;
|
||||||
|
Section->mTriangles = Triangles;
|
||||||
|
|
||||||
|
mSections.Add(Section);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Indices[4] = { -1, -1, -1, -1 };
|
||||||
|
|
||||||
|
for (int IndexIdx = 0; IndexIdx < LineType; IndexIdx++)
|
||||||
|
{
|
||||||
|
const lcVector3& Vertex = Vertices[IndexIdx];
|
||||||
|
|
||||||
|
for (int VertexIdx = mVertices.GetSize() - 1; VertexIdx >= 0; VertexIdx--)
|
||||||
|
{
|
||||||
|
if (Vertex == mVertices[VertexIdx])
|
||||||
|
{
|
||||||
|
Indices[IndexIdx] = VertexIdx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Indices[IndexIdx] == -1)
|
||||||
|
{
|
||||||
|
Indices[IndexIdx] = mVertices.GetSize();
|
||||||
|
mVertices.Add(Vertex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (LineType)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
Section->mIndices.Add(Indices[2]);
|
||||||
|
Section->mIndices.Add(Indices[3]);
|
||||||
|
Section->mIndices.Add(Indices[0]);
|
||||||
|
case 3:
|
||||||
|
Section->mIndices.Add(Indices[0]);
|
||||||
|
Section->mIndices.Add(Indices[1]);
|
||||||
|
Section->mIndices.Add(Indices[2]);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Section->mIndices.Add(Indices[0]);
|
||||||
|
Section->mIndices.Add(Indices[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcLibraryMeshData::AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, lcuint32 CurrentColorCode)
|
||||||
|
{
|
||||||
|
int VertexCount = Data.mVertices.GetSize();
|
||||||
|
ObjArray<lcuint32> IndexRemap(VertexCount);
|
||||||
|
|
||||||
|
mVertices.Expand(Data.mVertices.GetSize());
|
||||||
|
|
||||||
|
for (int SrcVertexIdx = 0; SrcVertexIdx < VertexCount; SrcVertexIdx++)
|
||||||
|
{
|
||||||
|
lcVector3 Vertex = lcMul31(Data.mVertices[SrcVertexIdx], Transform);
|
||||||
|
int Index = -1;
|
||||||
|
|
||||||
|
for (int DstVertexIdx = mVertices.GetSize() - 1; DstVertexIdx >= 0; DstVertexIdx--)
|
||||||
|
{
|
||||||
|
// if (Vertex == mVertices[DstVertexIdx])
|
||||||
|
if (fabsf(Vertex.x - mVertices[DstVertexIdx].x) < 0.25 && fabsf(Vertex.y - mVertices[DstVertexIdx].y) < 0.25 && fabsf(Vertex.z - mVertices[DstVertexIdx].z) < 0.25)
|
||||||
|
{
|
||||||
|
Index = DstVertexIdx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Index == -1)
|
||||||
|
{
|
||||||
|
Index = mVertices.GetSize();
|
||||||
|
mVertices.Add(Vertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexRemap.Add(Index);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int SrcSectionIdx = 0; SrcSectionIdx < Data.mSections.GetSize(); SrcSectionIdx++)
|
||||||
|
{
|
||||||
|
lcLibraryMeshSection* SrcSection = Data.mSections[SrcSectionIdx];
|
||||||
|
lcLibraryMeshSection* DstSection = NULL;
|
||||||
|
lcuint32 ColorCode = SrcSection->mColorCode == 16 ? CurrentColorCode : SrcSection->mColorCode;
|
||||||
|
|
||||||
|
for (int DstSectionIdx = 0; DstSectionIdx < mSections.GetSize(); DstSectionIdx++)
|
||||||
|
{
|
||||||
|
lcLibraryMeshSection* Section = mSections[DstSectionIdx];
|
||||||
|
|
||||||
|
if (Section->mColorCode == ColorCode && Section->mTriangles == SrcSection->mTriangles)
|
||||||
|
{
|
||||||
|
DstSection = Section;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DstSection)
|
||||||
|
{
|
||||||
|
DstSection = new lcLibraryMeshSection;
|
||||||
|
|
||||||
|
DstSection->mColorCode = ColorCode;
|
||||||
|
DstSection->mTriangles = SrcSection->mTriangles;
|
||||||
|
|
||||||
|
mSections.Add(DstSection);
|
||||||
|
}
|
||||||
|
|
||||||
|
DstSection->mIndices.Expand(SrcSection->mIndices.GetSize());
|
||||||
|
for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++)
|
||||||
|
DstSection->mIndices.Add(IndexRemap[SrcSection->mIndices[IndexIdx]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcLibraryMeshData::AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, lcuint32 CurrentColorCode)
|
||||||
|
{
|
||||||
|
lcuint32 BaseIndex = mVertices.GetSize();
|
||||||
|
|
||||||
|
mVertices.Expand(Data.mVertices.GetSize());
|
||||||
|
|
||||||
|
for (int SrcVertexIdx = 0; SrcVertexIdx < Data.mVertices.GetSize(); SrcVertexIdx++)
|
||||||
|
mVertices.Add(lcMul31(Data.mVertices[SrcVertexIdx], Transform));
|
||||||
|
|
||||||
|
for (int SrcSectionIdx = 0; SrcSectionIdx < Data.mSections.GetSize(); SrcSectionIdx++)
|
||||||
|
{
|
||||||
|
lcLibraryMeshSection* SrcSection = Data.mSections[SrcSectionIdx];
|
||||||
|
lcLibraryMeshSection* DstSection = NULL;
|
||||||
|
lcuint32 ColorCode = SrcSection->mColorCode == 16 ? CurrentColorCode : SrcSection->mColorCode;
|
||||||
|
|
||||||
|
for (int DstSectionIdx = 0; DstSectionIdx < mSections.GetSize(); DstSectionIdx++)
|
||||||
|
{
|
||||||
|
lcLibraryMeshSection* Section = mSections[DstSectionIdx];
|
||||||
|
|
||||||
|
if (Section->mColorCode == ColorCode && Section->mTriangles == SrcSection->mTriangles)
|
||||||
|
{
|
||||||
|
DstSection = Section;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DstSection)
|
||||||
|
{
|
||||||
|
DstSection = new lcLibraryMeshSection;
|
||||||
|
|
||||||
|
DstSection->mColorCode = ColorCode;
|
||||||
|
DstSection->mTriangles = SrcSection->mTriangles;
|
||||||
|
|
||||||
|
mSections.Add(DstSection);
|
||||||
|
}
|
||||||
|
|
||||||
|
DstSection->mIndices.Expand(SrcSection->mIndices.GetSize());
|
||||||
|
for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++)
|
||||||
|
DstSection->mIndices.Add(BaseIndex + SrcSection->mIndices[IndexIdx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,13 +1,82 @@
|
||||||
#ifndef _LC_LIBRARY_H_
|
#ifndef _LC_LIBRARY_H_
|
||||||
#define _LC_LIBRARY_H_
|
#define _LC_LIBRARY_H_
|
||||||
|
|
||||||
|
#include "lc_mesh.h"
|
||||||
|
#include "array.h"
|
||||||
|
|
||||||
|
class PieceInfo;
|
||||||
|
class lcZipFile;
|
||||||
|
|
||||||
|
class lcLibraryMeshSection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
lcLibraryMeshSection()
|
||||||
|
: mIndices(1024, 1024)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~lcLibraryMeshSection()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
lcuint32 mColorCode;
|
||||||
|
bool mTriangles;
|
||||||
|
ObjArray<lcuint32> mIndices;
|
||||||
|
};
|
||||||
|
|
||||||
|
class lcLibraryMeshData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
lcLibraryMeshData()
|
||||||
|
: mVertices(1024, 1024)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~lcLibraryMeshData()
|
||||||
|
{
|
||||||
|
for (int SectionIdx = 0; SectionIdx < mSections.GetSize(); SectionIdx++)
|
||||||
|
delete mSections[SectionIdx];
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddLine(int LineType, lcuint32 ColorCode, const lcVector3* Vertices);
|
||||||
|
void AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, lcuint32 CurrentColorCode);
|
||||||
|
void AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, lcuint32 CurrentColorCode);
|
||||||
|
|
||||||
|
PtrArray<lcLibraryMeshSection> mSections;
|
||||||
|
ObjArray<lcVector3> mVertices;
|
||||||
|
};
|
||||||
|
|
||||||
|
class lcLibraryPrimitive
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
char mName[LC_MAXPATH];
|
||||||
|
lcuint32 mZipFileIndex;
|
||||||
|
bool mLoaded;
|
||||||
|
bool mStud;
|
||||||
|
bool mSubFile;
|
||||||
|
lcLibraryMeshData mMeshData;
|
||||||
|
};
|
||||||
|
|
||||||
class lcPiecesLibrary
|
class lcPiecesLibrary
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
lcPiecesLibrary();
|
lcPiecesLibrary();
|
||||||
~lcPiecesLibrary();
|
~lcPiecesLibrary();
|
||||||
|
|
||||||
bool OpenArchive(const char* LibPath);
|
bool OpenArchive(const char* FileName);
|
||||||
|
|
||||||
|
|
||||||
|
bool LoadPiece(const char* PieceName);
|
||||||
|
bool LoadPiece(int PieceIndex);
|
||||||
|
int FindPrimitiveIndex(const char* Name);
|
||||||
|
bool LoadPrimitive(int PrimitiveIndex);
|
||||||
|
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcLibraryMeshData& MeshData);
|
||||||
|
|
||||||
|
PtrArray<PieceInfo> mPieces;
|
||||||
|
PtrArray<lcLibraryPrimitive> mPrimitives;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
lcZipFile* mZipFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _LC_LIBRARY_H_
|
#endif // _LC_LIBRARY_H_
|
||||||
|
|
|
@ -258,6 +258,11 @@ inline lcVector3& operator/=(lcVector3& a, float b)
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const lcVector3& a, const lcVector3& b)
|
||||||
|
{
|
||||||
|
return a.x == b.x && a.y == b.y && a.z == b.z;
|
||||||
|
}
|
||||||
|
|
||||||
inline void lcVector3::Normalize()
|
inline void lcVector3::Normalize()
|
||||||
{
|
{
|
||||||
float InvLength = 1.0f / Length();
|
float InvLength = 1.0f / Length();
|
||||||
|
|
|
@ -155,62 +155,62 @@ lcuint64 lcZipFile::SearchCentralDir64()
|
||||||
return RelativeOffset;
|
return RelativeOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lcZipFile::CheckFileCoherencyHeader(int FileIndex, lcuint32* SizeVar, lcuint64* OffsetLocalExtraField, lcuint32* SizeLocalExtraField)
|
bool lcZipFile::CheckFileCoherencyHeader(int FileIndex, lcuint32* SizeVar, lcuint64* OffsetLocalExtraField, lcuint32* SizeLocalExtraField)
|
||||||
{
|
{
|
||||||
lcuint16 Number16, Flags;
|
lcuint16 Number16, Flags;
|
||||||
lcuint32 Number32, Magic;
|
lcuint32 Number32, Magic;
|
||||||
lcuint16 SizeFilename, SizeExtraField;
|
lcuint16 SizeFilename, SizeExtraField;
|
||||||
const lcZipFileInfo& FileInfo = mFiles[FileIndex];
|
const lcZipFileInfo& FileInfo = mFiles[FileIndex];
|
||||||
|
|
||||||
*SizeVar = 0;
|
*SizeVar = 0;
|
||||||
*OffsetLocalExtraField = 0;
|
*OffsetLocalExtraField = 0;
|
||||||
*SizeLocalExtraField = 0;
|
*SizeLocalExtraField = 0;
|
||||||
|
|
||||||
mFile->Seek((long)(FileInfo.offset_curfile + mBytesBeforeZipFile), SEEK_SET);
|
mFile->Seek((long)(FileInfo.offset_curfile + mBytesBeforeZipFile), SEEK_SET);
|
||||||
|
|
||||||
if (mFile->ReadU32(&Magic, 1) != 1 || Magic != 0x04034b50)
|
if (mFile->ReadU32(&Magic, 1) != 1 || Magic != 0x04034b50)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mFile->ReadU16(&Number16, 1) != 1)
|
if (mFile->ReadU16(&Number16, 1) != 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mFile->ReadU16(&Flags, 1) != 1)
|
if (mFile->ReadU16(&Flags, 1) != 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mFile->ReadU16(&Number16, 1) != 1 || Number16 != FileInfo.compression_method)
|
if (mFile->ReadU16(&Number16, 1) != 1 || Number16 != FileInfo.compression_method)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (FileInfo.compression_method != 0 && FileInfo.compression_method != Z_DEFLATED)
|
if (FileInfo.compression_method != 0 && FileInfo.compression_method != Z_DEFLATED)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mFile->ReadU32(&Number32, 1) != 1)
|
if (mFile->ReadU32(&Number32, 1) != 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mFile->ReadU32(&Number32, 1) != 1 || ((Number32 != FileInfo.crc) && ((Flags & 8)==0)))
|
if (mFile->ReadU32(&Number32, 1) != 1 || ((Number32 != FileInfo.crc) && ((Flags & 8)==0)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mFile->ReadU32(&Number32, 1) != 1 || (Number32 != 0xFFFFFFFF && (Number32 != FileInfo.compressed_size) && ((Flags & 8)==0)))
|
if (mFile->ReadU32(&Number32, 1) != 1 || (Number32 != 0xFFFFFFFF && (Number32 != FileInfo.compressed_size) && ((Flags & 8)==0)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mFile->ReadU32(&Number32, 1) != 1 || (Number32 != 0xFFFFFFFF && (Number32 != FileInfo.uncompressed_size) && ((Flags & 8)==0)))
|
if (mFile->ReadU32(&Number32, 1) != 1 || (Number32 != 0xFFFFFFFF && (Number32 != FileInfo.uncompressed_size) && ((Flags & 8)==0)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mFile->ReadU16(&SizeFilename, 1) != 1 || SizeFilename != FileInfo.size_filename)
|
if (mFile->ReadU16(&SizeFilename, 1) != 1 || SizeFilename != FileInfo.size_filename)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
*SizeVar += SizeFilename;
|
*SizeVar += SizeFilename;
|
||||||
|
|
||||||
if (mFile->ReadU16(&SizeExtraField, 1) != 1)
|
if (mFile->ReadU16(&SizeExtraField, 1) != 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
*OffsetLocalExtraField= FileInfo.offset_curfile + 0x1e + SizeFilename;
|
*OffsetLocalExtraField= FileInfo.offset_curfile + 0x1e + SizeFilename;
|
||||||
*SizeLocalExtraField = SizeExtraField;
|
*SizeLocalExtraField = SizeExtraField;
|
||||||
|
|
||||||
*SizeVar += SizeExtraField;
|
*SizeVar += SizeExtraField;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lcZipFile::Open()
|
bool lcZipFile::Open()
|
||||||
{
|
{
|
||||||
lcuint64 NumberEntriesCD, CentralPos;
|
lcuint64 NumberEntriesCD, CentralPos;
|
||||||
|
@ -312,9 +312,6 @@ bool lcZipFile::Open()
|
||||||
mBytesBeforeZipFile = CentralPos - (mCentralDirOffset + mCentralDirSize);
|
mBytesBeforeZipFile = CentralPos - (mCentralDirOffset + mCentralDirSize);
|
||||||
mCentralPos = CentralPos;
|
mCentralPos = CentralPos;
|
||||||
|
|
||||||
// us.pfile_in_zip_read = NULL;
|
|
||||||
// us.encrypted = 0;
|
|
||||||
|
|
||||||
return ReadCentralDir();
|
return ReadCentralDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,193 +535,144 @@ bool lcZipFile::ReadCentralDir()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lcZipFile::ExtractFile(int FileIndex, lcMemFile& File)
|
bool lcZipFile::ExtractFile(int FileIndex, lcMemFile& File, lcuint32 MaxLength)
|
||||||
{
|
{
|
||||||
lcuint32 SizeVar;
|
lcuint32 SizeVar;
|
||||||
lcuint64 OffsetLocalExtraField;
|
lcuint64 OffsetLocalExtraField;
|
||||||
lcuint32 SizeLocalExtraField;
|
lcuint32 SizeLocalExtraField;
|
||||||
const lcZipFileInfo& FileInfo = mFiles[FileIndex];
|
const lcZipFileInfo& FileInfo = mFiles[FileIndex];
|
||||||
const int BufferSize = 16384;
|
|
||||||
|
|
||||||
if (!CheckFileCoherencyHeader(FileIndex, &SizeVar, &OffsetLocalExtraField, &SizeLocalExtraField))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// file_in_zip_read_info_s contain internal information about a file in zipfile, when reading and decompress it
|
|
||||||
struct file_in_zip64_read_info
|
|
||||||
{
|
|
||||||
char read_buffer[BufferSize]; // internal buffer for compressed data
|
|
||||||
z_stream stream; // zLib stream structure for inflate
|
|
||||||
|
|
||||||
lcuint64 pos_in_zipfile; // position in byte on the zipfile, for fseek
|
|
||||||
lcuint32 stream_initialised; // flag set if stream structure is initialised
|
|
||||||
|
|
||||||
lcuint64 offset_local_extrafield; // offset of the local extra field
|
|
||||||
lcuint32 size_local_extrafield; // size of the local extra field
|
|
||||||
lcuint64 pos_local_extrafield; // position in the local extra field in read
|
|
||||||
lcuint64 total_out_64;
|
|
||||||
|
|
||||||
lcuint32 crc32; // crc32 of all data uncompressed
|
|
||||||
lcuint32 crc32_wait; // crc32 we must obtain after decompress all
|
|
||||||
lcuint64 rest_read_compressed; // number of byte to be decompressed
|
|
||||||
lcuint64 rest_read_uncompressed; //number of byte to be obtained after decomp
|
|
||||||
// zlib_filefunc64_32_def z_filefunc;
|
|
||||||
// voidpf filestream; // io structore of the zipfile
|
|
||||||
lcuint32 compression_method; // compression method (0==store)
|
|
||||||
lcuint64 byte_before_the_zipfile; // byte before the zipfile, (>0 for sfx)
|
|
||||||
int raw;
|
|
||||||
};
|
|
||||||
|
|
||||||
file_in_zip64_read_info ReadInfo;
|
if (!CheckFileCoherencyHeader(FileIndex, &SizeVar, &OffsetLocalExtraField, &SizeLocalExtraField))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const int BufferSize = 16384;
|
||||||
|
char ReadBuffer[BufferSize];
|
||||||
|
z_stream Stream;
|
||||||
|
lcuint32 Crc32;
|
||||||
|
lcuint64 PosInZipfile;
|
||||||
|
lcuint64 RestReadCompressed;
|
||||||
|
lcuint64 RestReadUncompressed;
|
||||||
|
|
||||||
|
Crc32 = 0;
|
||||||
|
Stream.total_out = 0;
|
||||||
|
|
||||||
|
if (FileInfo.compression_method == Z_DEFLATED)
|
||||||
|
{
|
||||||
|
Stream.zalloc = (alloc_func)0;
|
||||||
|
Stream.zfree = (free_func)0;
|
||||||
|
Stream.opaque = (voidpf)0;
|
||||||
|
Stream.next_in = 0;
|
||||||
|
Stream.avail_in = 0;
|
||||||
|
|
||||||
|
int err = inflateInit2(&Stream, -MAX_WBITS);
|
||||||
|
if (err != Z_OK)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RestReadCompressed = FileInfo.compressed_size;
|
||||||
|
RestReadUncompressed = FileInfo.uncompressed_size;
|
||||||
|
PosInZipfile = FileInfo.offset_curfile + 0x1e + SizeVar;
|
||||||
|
|
||||||
|
Stream.avail_in = (uInt)0;
|
||||||
|
|
||||||
|
lcuint32 Length = lcMin((lcuint32)FileInfo.uncompressed_size, MaxLength);
|
||||||
|
File.SetLength(Length);
|
||||||
|
File.Seek(0, SEEK_SET);
|
||||||
|
|
||||||
|
Stream.next_out = (Bytef*)File.mBuffer;
|
||||||
|
Stream.avail_out = Length;
|
||||||
|
|
||||||
|
lcuint32 Read = 0;
|
||||||
|
|
||||||
|
while (Stream.avail_out > 0)
|
||||||
|
{
|
||||||
|
if ((Stream.avail_in == 0) && (RestReadCompressed > 0))
|
||||||
|
{
|
||||||
|
lcuint32 ReadThis = BufferSize;
|
||||||
|
|
||||||
|
if (RestReadCompressed < ReadThis)
|
||||||
|
ReadThis = (lcuint32)RestReadCompressed;
|
||||||
|
|
||||||
|
if (ReadThis == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mFile->Seek((long)(PosInZipfile + mBytesBeforeZipFile), SEEK_SET);
|
||||||
|
if (mFile->ReadBuffer(ReadBuffer, ReadThis) != ReadThis)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
PosInZipfile += ReadThis;
|
||||||
|
|
||||||
|
RestReadCompressed -= ReadThis;
|
||||||
|
|
||||||
|
Stream.next_in = (Bytef*)ReadBuffer;
|
||||||
|
Stream.avail_in = (uInt)ReadThis;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FileInfo.compression_method == 0)
|
||||||
|
{
|
||||||
|
lcuint32 DoCopy, i;
|
||||||
|
|
||||||
|
if ((Stream.avail_in == 0) && (RestReadCompressed == 0))
|
||||||
|
return (Read == 0) ? false : true;
|
||||||
|
|
||||||
|
if (Stream.avail_out < Stream.avail_in)
|
||||||
|
DoCopy = Stream.avail_out;
|
||||||
|
else
|
||||||
|
DoCopy = Stream.avail_in;
|
||||||
|
|
||||||
|
for (i = 0; i < DoCopy; i++)
|
||||||
|
*(Stream.next_out+i) = *(Stream.next_in+i);
|
||||||
|
|
||||||
|
Crc32 = crc32(Crc32, Stream.next_out, DoCopy);
|
||||||
|
RestReadUncompressed -= DoCopy;
|
||||||
|
Stream.avail_in -= DoCopy;
|
||||||
|
Stream.avail_out -= DoCopy;
|
||||||
|
Stream.next_out += DoCopy;
|
||||||
|
Stream.next_in += DoCopy;
|
||||||
|
Stream.total_out += DoCopy;
|
||||||
|
Read += DoCopy;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lcuint64 TotalOutBefore, TotalOutAfter;
|
||||||
|
const Bytef *bufBefore;
|
||||||
|
lcuint64 OutThis;
|
||||||
|
int flush = Z_SYNC_FLUSH;
|
||||||
|
|
||||||
|
TotalOutBefore = Stream.total_out;
|
||||||
|
bufBefore = Stream.next_out;
|
||||||
|
|
||||||
|
int err = inflate(&Stream,flush);
|
||||||
|
|
||||||
|
if ((err >= 0) && (Stream.msg != NULL))
|
||||||
|
err = Z_DATA_ERROR;
|
||||||
|
|
||||||
|
TotalOutAfter = Stream.total_out;
|
||||||
|
OutThis = TotalOutAfter - TotalOutBefore;
|
||||||
|
|
||||||
|
Crc32 = crc32(Crc32, bufBefore, (uInt)(OutThis));
|
||||||
|
|
||||||
|
RestReadUncompressed -= OutThis;
|
||||||
|
|
||||||
|
Read += (uInt)(TotalOutAfter - TotalOutBefore);
|
||||||
|
|
||||||
|
if (err != Z_OK)
|
||||||
|
{
|
||||||
|
inflateEnd(&Stream);
|
||||||
|
|
||||||
|
if (RestReadUncompressed == 0)
|
||||||
|
{
|
||||||
|
if (Crc32 != FileInfo.crc)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == Z_STREAM_END)
|
||||||
|
return (Read == 0) ? false : true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ReadInfo.offset_local_extrafield = OffsetLocalExtraField;
|
|
||||||
ReadInfo.size_local_extrafield = SizeLocalExtraField;
|
|
||||||
ReadInfo.pos_local_extrafield = 0;
|
|
||||||
ReadInfo.raw = 0;
|
|
||||||
|
|
||||||
ReadInfo.stream_initialised=0;
|
|
||||||
|
|
||||||
ReadInfo.crc32_wait = FileInfo.crc;
|
|
||||||
ReadInfo.crc32 = 0;
|
|
||||||
ReadInfo.total_out_64 = 0;
|
|
||||||
ReadInfo.compression_method = FileInfo.compression_method;
|
|
||||||
// ReadInfo.filestream = s->filestream;
|
|
||||||
// ReadInfo.z_filefunc = s->z_filefunc;
|
|
||||||
ReadInfo.byte_before_the_zipfile = mBytesBeforeZipFile;
|
|
||||||
|
|
||||||
ReadInfo.stream.total_out = 0;
|
|
||||||
|
|
||||||
if (FileInfo.compression_method == Z_DEFLATED)
|
|
||||||
{
|
|
||||||
ReadInfo.stream.zalloc = (alloc_func)0;
|
|
||||||
ReadInfo.stream.zfree = (free_func)0;
|
|
||||||
ReadInfo.stream.opaque = (voidpf)0;
|
|
||||||
ReadInfo.stream.next_in = 0;
|
|
||||||
ReadInfo.stream.avail_in = 0;
|
|
||||||
|
|
||||||
int err=inflateInit2(&ReadInfo.stream, -MAX_WBITS);
|
|
||||||
if (err == Z_OK)
|
|
||||||
ReadInfo.stream_initialised = Z_DEFLATED;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadInfo.rest_read_compressed = FileInfo.compressed_size;
|
|
||||||
ReadInfo.rest_read_uncompressed = FileInfo.uncompressed_size;
|
|
||||||
ReadInfo.pos_in_zipfile = FileInfo.offset_curfile + 0x1e + SizeVar;
|
|
||||||
|
|
||||||
ReadInfo.stream.avail_in = (uInt)0;
|
|
||||||
|
|
||||||
// s->pfile_in_zip_read = pfile_in_zip_read_info;
|
|
||||||
// s->encrypted = 0;
|
|
||||||
|
|
||||||
File.SetLength((long)FileInfo.uncompressed_size);
|
|
||||||
File.Seek(0, SEEK_SET);
|
|
||||||
|
|
||||||
ReadInfo.stream.next_out = (Bytef*)File.mBuffer;
|
|
||||||
ReadInfo.stream.avail_out = File.mBufferSize;
|
|
||||||
|
|
||||||
// if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && (!(pfile_in_zip_read_info->raw)))
|
|
||||||
// pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
|
|
||||||
|
|
||||||
// if ((len>pfile_in_zip_read_info->rest_read_compressed+pfile_in_zip_read_info->stream.avail_in) && (pfile_in_zip_read_info->raw))
|
|
||||||
// pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_compressed+pfile_in_zip_read_info->stream.avail_in;
|
|
||||||
|
|
||||||
lcuint32 Read = 0;
|
|
||||||
|
|
||||||
while (ReadInfo.stream.avail_out > 0)
|
|
||||||
{
|
|
||||||
if ((ReadInfo.stream.avail_in == 0) && (ReadInfo.rest_read_compressed > 0))
|
|
||||||
{
|
|
||||||
lcuint32 ReadThis = BufferSize;
|
|
||||||
|
|
||||||
if (ReadInfo.rest_read_compressed < ReadThis)
|
|
||||||
ReadThis = (lcuint32)ReadInfo.rest_read_compressed;
|
|
||||||
|
|
||||||
if (ReadThis == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
mFile->Seek((long)(ReadInfo.pos_in_zipfile + ReadInfo.byte_before_the_zipfile), SEEK_SET);
|
|
||||||
if (mFile->ReadBuffer(ReadInfo.read_buffer, ReadThis) != ReadThis)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ReadInfo.pos_in_zipfile += ReadThis;
|
|
||||||
|
|
||||||
ReadInfo.rest_read_compressed -= ReadThis;
|
|
||||||
|
|
||||||
ReadInfo.stream.next_in = (Bytef*)ReadInfo.read_buffer;
|
|
||||||
ReadInfo.stream.avail_in = (uInt)ReadThis;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ReadInfo.compression_method == 0)
|
|
||||||
{
|
|
||||||
lcuint32 DoCopy, i;
|
|
||||||
|
|
||||||
if ((ReadInfo.stream.avail_in == 0) && (ReadInfo.rest_read_compressed == 0))
|
|
||||||
return (Read == 0) ? false : true;
|
|
||||||
|
|
||||||
if (ReadInfo.stream.avail_out <
|
|
||||||
ReadInfo.stream.avail_in)
|
|
||||||
DoCopy = ReadInfo.stream.avail_out;
|
|
||||||
else
|
|
||||||
DoCopy = ReadInfo.stream.avail_in;
|
|
||||||
|
|
||||||
for (i = 0; i < DoCopy; i++)
|
|
||||||
*(ReadInfo.stream.next_out+i) = *(ReadInfo.stream.next_in+i);
|
|
||||||
|
|
||||||
ReadInfo.total_out_64 = ReadInfo.total_out_64 + DoCopy;
|
|
||||||
|
|
||||||
ReadInfo.crc32 = crc32(ReadInfo.crc32, ReadInfo.stream.next_out, DoCopy);
|
|
||||||
ReadInfo.rest_read_uncompressed -= DoCopy;
|
|
||||||
ReadInfo.stream.avail_in -= DoCopy;
|
|
||||||
ReadInfo.stream.avail_out -= DoCopy;
|
|
||||||
ReadInfo.stream.next_out += DoCopy;
|
|
||||||
ReadInfo.stream.next_in += DoCopy;
|
|
||||||
ReadInfo.stream.total_out += DoCopy;
|
|
||||||
Read += DoCopy;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lcuint64 TotalOutBefore, TotalOutAfter;
|
|
||||||
const Bytef *bufBefore;
|
|
||||||
lcuint64 OutThis;
|
|
||||||
int flush = Z_SYNC_FLUSH;
|
|
||||||
|
|
||||||
TotalOutBefore = ReadInfo.stream.total_out;
|
|
||||||
bufBefore = ReadInfo.stream.next_out;
|
|
||||||
|
|
||||||
int err = inflate(&ReadInfo.stream,flush);
|
|
||||||
|
|
||||||
if ((err >= 0) && (ReadInfo.stream.msg != NULL))
|
|
||||||
err = Z_DATA_ERROR;
|
|
||||||
|
|
||||||
TotalOutAfter = ReadInfo.stream.total_out;
|
|
||||||
OutThis = TotalOutAfter - TotalOutBefore;
|
|
||||||
|
|
||||||
ReadInfo.total_out_64 = ReadInfo.total_out_64 + OutThis;
|
|
||||||
|
|
||||||
ReadInfo.crc32 = crc32(ReadInfo.crc32,bufBefore, (uInt)(OutThis));
|
|
||||||
|
|
||||||
ReadInfo.rest_read_uncompressed -= OutThis;
|
|
||||||
|
|
||||||
Read += (uInt)(TotalOutAfter - TotalOutBefore);
|
|
||||||
|
|
||||||
if (err != Z_OK)
|
|
||||||
{
|
|
||||||
inflateEnd(&ReadInfo.stream);
|
|
||||||
|
|
||||||
if (ReadInfo.rest_read_uncompressed == 0)
|
|
||||||
{
|
|
||||||
if (ReadInfo.crc32 != ReadInfo.crc32_wait)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err == Z_STREAM_END)
|
|
||||||
return (Read == 0) ? false : true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
~lcZipFile();
|
~lcZipFile();
|
||||||
|
|
||||||
bool Open(const char* FilePath);
|
bool Open(const char* FilePath);
|
||||||
bool ExtractFile(int FileIndex, lcMemFile& File);
|
bool ExtractFile(int FileIndex, lcMemFile& File, lcuint32 MaxLength = 0xffffffff);
|
||||||
|
|
||||||
ObjArray<lcZipFileInfo> mFiles;
|
ObjArray<lcZipFileInfo> mFiles;
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ protected:
|
||||||
bool ReadCentralDir();
|
bool ReadCentralDir();
|
||||||
lcuint64 SearchCentralDir();
|
lcuint64 SearchCentralDir();
|
||||||
lcuint64 SearchCentralDir64();
|
lcuint64 SearchCentralDir64();
|
||||||
bool CheckFileCoherencyHeader(int FileIndex, lcuint32* SizeVar, lcuint64* OffsetLocalExtraField, lcuint32* SizeLocalExtraField);
|
bool CheckFileCoherencyHeader(int FileIndex, lcuint32* SizeVar, lcuint64* OffsetLocalExtraField, lcuint32* SizeLocalExtraField);
|
||||||
|
|
||||||
lcFile* mFile;
|
lcFile* mFile;
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,8 @@ static float costbl[SIDES];
|
||||||
|
|
||||||
PieceInfo::PieceInfo()
|
PieceInfo::PieceInfo()
|
||||||
{
|
{
|
||||||
|
m_nRef = 0;
|
||||||
|
m_nBoxList = 0;
|
||||||
mMesh = NULL;
|
mMesh = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,10 +70,6 @@ void PieceInfo::LoadIndex(lcFile& file)
|
||||||
init = true;
|
init = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: don't change ref. if we're reloading ?
|
|
||||||
m_nRef = 0;
|
|
||||||
m_nBoxList = 0;
|
|
||||||
|
|
||||||
file.ReadBuffer(m_strName, LC_PIECE_NAME_LEN);
|
file.ReadBuffer(m_strName, LC_PIECE_NAME_LEN);
|
||||||
file.ReadBuffer(m_strDescription, 64);
|
file.ReadBuffer(m_strDescription, 64);
|
||||||
m_strDescription[64] = '\0';
|
m_strDescription[64] = '\0';
|
||||||
|
@ -100,9 +98,6 @@ void PieceInfo::LoadIndex(lcFile& file)
|
||||||
|
|
||||||
void PieceInfo::CreatePlaceholder(const char* Name)
|
void PieceInfo::CreatePlaceholder(const char* Name)
|
||||||
{
|
{
|
||||||
m_nRef = 0;
|
|
||||||
m_nBoxList = 0;
|
|
||||||
|
|
||||||
strncpy(m_strName, Name, sizeof(m_strName));
|
strncpy(m_strName, Name, sizeof(m_strName));
|
||||||
m_strName[sizeof(m_strName)-1] = 0;
|
m_strName[sizeof(m_strName)-1] = 0;
|
||||||
strncpy(m_strDescription, Name, sizeof(m_strDescription));
|
strncpy(m_strDescription, Name, sizeof(m_strDescription));
|
||||||
|
|
|
@ -80,7 +80,7 @@ public:
|
||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
char m_strName[LC_PIECE_NAME_LEN];
|
char m_strName[LC_PIECE_NAME_LEN];
|
||||||
char m_strDescription[65];
|
char m_strDescription[128];
|
||||||
float m_fDimensions[6];
|
float m_fDimensions[6];
|
||||||
lcuint32 m_nOffset;
|
lcuint32 m_nOffset;
|
||||||
lcuint32 m_nSize;
|
lcuint32 m_nSize;
|
||||||
|
|
Loading…
Reference in a new issue