2020-05-19 09:00:24 +02:00
|
|
|
#include "newlevel.h"
|
|
|
|
#include "../Specific/IO/ChunkId.h"
|
|
|
|
#include "../Specific/IO/ChunkReader.h"
|
|
|
|
|
|
|
|
TrLevel::TrLevel(string filename)
|
|
|
|
{
|
|
|
|
m_filename = filename;
|
|
|
|
}
|
|
|
|
|
|
|
|
TrLevel::~TrLevel()
|
|
|
|
{
|
|
|
|
delete m_chunkTextureAtlas;
|
|
|
|
delete m_chunkTextureColor;
|
|
|
|
delete m_chunkTextureNormalMap;
|
|
|
|
delete m_chunkRoom;
|
|
|
|
delete m_chunkRoomInfo;
|
|
|
|
delete m_chunkBucket;
|
|
|
|
delete m_chunkRoomLight;
|
|
|
|
delete m_chunkRoomStatic;
|
|
|
|
delete m_chunkRoomPortal;
|
|
|
|
delete m_chunkRoomSector;
|
|
|
|
delete m_chunkRoomTriggerVolume;
|
|
|
|
delete m_chunkRoomClimbVolume;
|
|
|
|
delete m_chunkMaterial;
|
|
|
|
delete m_chunkVerticesPositions;
|
|
|
|
delete m_chunkVerticesNormals;
|
|
|
|
delete m_chunkVerticesTextureCoords;
|
|
|
|
delete m_chunkVerticesColors;
|
|
|
|
delete m_chunkVerticesEffects;
|
|
|
|
delete m_chunkVerticesBones;
|
|
|
|
delete m_chunkPolygon;
|
|
|
|
delete m_chunkMesh;
|
|
|
|
delete m_chunkBone;
|
|
|
|
delete m_chunkKeyFrame;
|
|
|
|
delete m_chunkAnimCommand;
|
|
|
|
delete m_chunkStateChange;
|
|
|
|
delete m_chunkAnimDispatch;
|
|
|
|
delete m_chunkAnimation;
|
|
|
|
delete m_chunkMoveable;
|
|
|
|
delete m_chunkStatic;
|
|
|
|
delete m_chunkItem;
|
|
|
|
delete m_chunkAiItem;
|
|
|
|
delete m_chunkCamera;
|
|
|
|
delete m_chunkSink;
|
|
|
|
delete m_chunkFlybyCamera;
|
|
|
|
delete m_chunkSoundSource;
|
|
|
|
delete m_chunkBox;
|
|
|
|
delete m_chunkOverlap;
|
|
|
|
delete m_chunkZone;
|
|
|
|
delete m_chunkSoundMap;
|
|
|
|
delete m_chunkSoundDetail;
|
|
|
|
delete m_chunkSample;
|
|
|
|
delete m_chunkLeelScript;
|
|
|
|
delete m_chunkSprite;
|
|
|
|
delete m_chunkSpriteSequence;
|
|
|
|
delete m_chunkDummy;
|
|
|
|
delete m_chunkAnimatedTextureSequence;
|
|
|
|
delete m_chunkAnimatedTextureFrame;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TrLevel::Load()
|
|
|
|
{
|
|
|
|
m_stream = new FileStream(m_filename.c_str, true, false);
|
|
|
|
m_reader = new ChunkReader(m_magicNumber, m_stream);
|
|
|
|
|
|
|
|
// Read chunks
|
2020-05-19 20:27:40 +02:00
|
|
|
m_reader->ReadChunks([this](ChunkId* id, long size, int arg) {
|
|
|
|
if (id->EqualsTo(m_chunkTextureAtlas))
|
|
|
|
return readTexture();
|
|
|
|
else if (id->EqualsTo(m_chunkAnimatedTextureSequence))
|
|
|
|
return readAnimatedTextureSequence();
|
|
|
|
else if (id->EqualsTo(m_chunkRoom))
|
|
|
|
return readRoom();
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}, 0);
|
2020-05-19 09:00:24 +02:00
|
|
|
|
|
|
|
// Close the stream
|
|
|
|
m_stream->Close();
|
|
|
|
//delete m_writer;
|
|
|
|
//delete m_stream;
|
|
|
|
}
|
|
|
|
|
|
|
|
ChunkReader* m_reader;
|
|
|
|
|
2020-05-19 20:27:40 +02:00
|
|
|
bool TrLevel::readTexture()
|
2020-05-19 09:00:24 +02:00
|
|
|
{
|
2020-05-19 20:27:40 +02:00
|
|
|
TrTexturePage texture;
|
2020-05-19 09:00:24 +02:00
|
|
|
|
2020-05-19 20:27:40 +02:00
|
|
|
m_stream->ReadInt32(&texture.width);
|
|
|
|
m_stream->ReadInt32(&texture.height);
|
|
|
|
m_stream->ReadInt32(&texture.format);
|
|
|
|
m_stream->ReadInt32(&texture.flags);
|
|
|
|
|
|
|
|
m_reader->ReadChunks([this, texture](ChunkId * id, long size, int arg) {
|
|
|
|
if (id->EqualsTo(m_chunkTextureColor))
|
|
|
|
{
|
|
|
|
int imageSize;
|
|
|
|
m_stream->ReadInt32(&imageSize);
|
|
|
|
m_stream->ReadBytes(texture.colorMap, imageSize);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}, 0);
|
|
|
|
|
|
|
|
textures.push_back(texture);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TrLevel::readAnimatedTextureSequence()
|
|
|
|
{
|
|
|
|
TrAnimatedTexturesSequence sequence;
|
|
|
|
|
|
|
|
m_stream->ReadByte(&sequence.animationType);
|
|
|
|
m_stream->ReadFloat(&sequence.fps);
|
|
|
|
m_stream->ReadInt32(&sequence.uvRotate);
|
|
|
|
|
|
|
|
m_reader->ReadChunks([this, sequence](ChunkId * id, long size, int arg) {
|
|
|
|
if (id->EqualsTo(m_chunkAnimatedTextureFrame))
|
|
|
|
{
|
|
|
|
TrAnimatedTexturesFrame frame;
|
|
|
|
|
|
|
|
m_stream->ReadInt32(&frame.texture);
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
Vector2 texCoords;
|
|
|
|
m_stream->ReadVector2(&texCoords);
|
|
|
|
frame.textureCoords.push_back(texCoords);
|
|
|
|
}
|
|
|
|
|
|
|
|
sequence.frames.push_back(frame);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}, 0);
|
|
|
|
|
|
|
|
animatedTextures.push_back(sequence);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TrLevel::readRoom()
|
|
|
|
{
|
|
|
|
TrRoom room;
|
|
|
|
|
|
|
|
m_stream->ReadInt32(&room.x);
|
|
|
|
m_stream->ReadInt32(&room.z);
|
|
|
|
m_stream->ReadInt32(&room.yBottom);
|
|
|
|
m_stream->ReadInt32(&room.yTop);
|
|
|
|
m_stream->ReadInt16(&room.numXsectors);
|
|
|
|
m_stream->ReadInt16(&room.numZsectors);
|
|
|
|
m_stream->ReadInt16(&room.roomType);
|
|
|
|
m_stream->ReadInt16(&room.effect);
|
|
|
|
m_stream->ReadFloat(&room.effectStrength);
|
|
|
|
m_stream->ReadInt16(&room.alternateRoom);
|
|
|
|
m_stream->ReadInt16(&room.alternatGroup);
|
|
|
|
m_stream->ReadInt32(&room.flags);
|
|
|
|
m_stream->ReadVector3(&room.ambient);
|
|
|
|
|
|
|
|
m_reader->ReadChunks([this, room](ChunkId * id, long size, int arg) {
|
|
|
|
if (id->EqualsTo(m_chunkBucket))
|
|
|
|
{
|
|
|
|
TrBucket bucket;
|
|
|
|
readBucket(&bucket);
|
|
|
|
room.buckets.push_back(bucket);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (id->EqualsTo(m_chunkRoomLight))
|
|
|
|
{
|
|
|
|
TrLight light;
|
|
|
|
m_stream->ReadVector3(&light.position);
|
|
|
|
m_stream->ReadVector3(&light.color);
|
|
|
|
m_stream->ReadVector3(&light.direction);
|
|
|
|
m_stream->ReadByte(&light.type);
|
|
|
|
m_stream->ReadBool(&light.castShadows);
|
|
|
|
m_stream->ReadFloat(&light.intensity);
|
|
|
|
m_stream->ReadFloat(&light.in);
|
|
|
|
m_stream->ReadFloat(&light.out);
|
|
|
|
m_stream->ReadFloat(&light.len);
|
|
|
|
m_stream->ReadFloat(&light.cutoff);
|
|
|
|
m_stream->ReadInt32(&light.flags);
|
|
|
|
m_reader->ReadChunks([this, room](ChunkId * id, long size, int arg) { return false; }, 0);
|
|
|
|
room.lights.push_back(light);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}, 0);
|
2020-05-19 09:00:24 +02:00
|
|
|
}
|
|
|
|
|
2020-05-19 20:27:40 +02:00
|
|
|
bool TrLevel::readBucket(TrBucket* bucket)
|
2020-05-19 09:00:24 +02:00
|
|
|
{
|
2020-05-19 20:27:40 +02:00
|
|
|
m_reader->ReadChunks([this, bucket](ChunkId * id, long size, int arg) {
|
|
|
|
if (id->EqualsTo(m_chunkMaterial))
|
|
|
|
{
|
|
|
|
m_stream->ReadInt32(&bucket->material.texture);
|
|
|
|
m_stream->ReadByte(&bucket->material.blendMode);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (id->EqualsTo(m_chunkVerticesPositions))
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
m_stream->ReadInt32(&count);
|
|
|
|
for (int i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
Vector3 vec;
|
|
|
|
m_stream->ReadVector3(&vec);
|
|
|
|
bucket->positions.push_back(vec);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (id->EqualsTo(m_chunkVerticesNormals))
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
m_stream->ReadInt32(&count);
|
|
|
|
for (int i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
Vector3 vec;
|
|
|
|
m_stream->ReadVector3(&vec);
|
|
|
|
bucket->normals.push_back(vec);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (id->EqualsTo(m_chunkVerticesColors))
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
m_stream->ReadInt32(&count);
|
|
|
|
for (int i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
Vector3 vec;
|
|
|
|
m_stream->ReadVector3(&vec);
|
|
|
|
bucket->colors.push_back(vec);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (id->EqualsTo(m_chunkVerticesTextureCoords))
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
m_stream->ReadInt32(&count);
|
|
|
|
for (int i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
Vector2 vec;
|
|
|
|
m_stream->ReadVector2(&vec);
|
|
|
|
bucket->textureCoords.push_back(vec);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (id->EqualsTo(m_chunkVerticesEffects))
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
m_stream->ReadInt32(&count);
|
|
|
|
for (int i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
int fx;
|
|
|
|
m_stream->ReadInt32(&fx);
|
|
|
|
bucket->verticesEffects.push_back(fx);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (id->EqualsTo(m_chunkVerticesBones))
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
m_stream->ReadInt32(&count);
|
|
|
|
for (int i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
int bone;
|
|
|
|
m_stream->ReadInt32(&bone);
|
|
|
|
bucket->bones.push_back(bone);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (id->EqualsTo(m_chunkPolygon))
|
|
|
|
{
|
|
|
|
TrPolygon polygon;
|
|
|
|
|
|
|
|
int count;
|
|
|
|
m_stream->ReadInt32(&count);
|
|
|
|
for (int i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
int index;
|
|
|
|
m_stream->ReadInt32(&index);
|
|
|
|
polygon.indices.push_back(index);
|
|
|
|
}
|
|
|
|
m_stream->ReadInt16(&polygon.animatedSequence);
|
|
|
|
m_stream->ReadInt16(&polygon.frame);
|
|
|
|
bucket->polygons.push_back(polygon);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}, 0);
|
2020-05-19 09:00:24 +02:00
|
|
|
}
|