static void ExtractMeshes(Tr2Level Level, byte[] MeshData, uint NumMeshPointers, uint[] MeshPointers) { bool NegativeSize; //Tr2Level Level = Level; Level.NumMeshes = (int) NumMeshPointers; Level.Meshes = new Tr2Mesh[Level.NumMeshes]; //create a stream reader MemoryStream meshDataStream = new MemoryStream(MeshData); BinaryReader meshReader = new BinaryReader(meshDataStream); // get mesh start //print("NumMeshPointers"+ NumMeshPointers); for (uint i = 0; i < NumMeshPointers; i++) { //get mesh start //print("MeshPointers["+i+"]"+ (int)MeshPointers[i]); int meshDataStartIndex = (int)MeshPointers[i]; //seek to meshDataStartIndex -> MeshPointer //byte meshDataStartByte = MeshData[meshDataStartIndex]; meshDataStream.Seek(meshDataStartIndex,SeekOrigin.Begin); //read mesh center //int sizetr2Vertex = 6; //int sizetr2Vertex = Tr2VertexSize; byte[] bcenter = meshReader.ReadBytes(Tr2VertexSize); Level.Meshes[i].Centre =(Tr2Vertex) Cast2Struct(bcenter,typeof (Tr2Vertex)); //dummy read for bunkown meshReader.ReadBytes(4); //print("center:" + Level.Meshes[i].Centre.x+ " "+ Level.Meshes[i].Centre.y +" "+ Level.Meshes[i].Centre.z); //get number of vertices Level.Meshes[i].NumVertices = meshReader.ReadInt16(); //print("Level.Meshes["+i+"].NumVertices" + Level.Meshes[i].NumVertices); Level.Meshes[i].NumVertices = (short) Mathf.Abs(Level.Meshes[i].NumVertices); //get vertex list int sizeVertices = Tr2VertexSize * Level.Meshes[i].NumVertices; Level.Meshes[i].Vertices = new Tr2Vertex [sizeVertices]; for(int vtxCnt = 0; vtxCnt < Level.Meshes[i].NumVertices ; vtxCnt++) { byte[] vtxData = meshReader.ReadBytes(Tr2VertexSize); Level.Meshes[i].Vertices[vtxCnt] = (Tr2Vertex) Cast2Struct(vtxData,typeof(Tr2Vertex)); } //get number of normals Level.Meshes[i].NumNormals = meshReader.ReadInt16(); NegativeSize = (Level.Meshes[i].NumNormals < 0); Level.Meshes[i].NumNormals = (short)Mathf.Abs(Level.Meshes[i].NumNormals); //get normal list if (NegativeSize) { //now Level.Meshes[i].NumNormals mean number of MeshLights int numMeshLights = Level.Meshes[i].NumNormals; Level.Meshes[i].MeshLights = new short[numMeshLights]; //could be turned in to byte array for(int meshLightCount = 0; meshLightCount < numMeshLights ; meshLightCount++) { Level.Meshes[i].MeshLights[meshLightCount] = meshReader.ReadInt16(); } NegativeSize = false; } else { int numMeshNormals = Level.Meshes[i].NumNormals; Level.Meshes[i].Normals = new Tr2Vertex[numMeshNormals]; for(int nrmCount = 0 ; nrmCount < numMeshNormals; nrmCount++) { byte[] normData = meshReader.ReadBytes(Tr2VertexSize); Level.Meshes[i].Normals[nrmCount] = (Tr2Vertex) Cast2Struct(normData,typeof(Tr2Vertex)); } } // get list of textured rectangles Level.Meshes[i].NumTexturedRectangles = meshReader.ReadInt16(); Level.Meshes[i].NumTexturedRectangles = (short) Mathf.Abs(Level.Meshes[i].NumTexturedRectangles); //print("Level.Meshes["+i+"].NumTexturedRectangles " + Level.Meshes[i].NumTexturedRectangles); if (Level.Meshes[i].NumTexturedRectangles > 0) { Level.Meshes[i].TexturedRectangles = new Tr2Face4[Level.Meshes[i].NumTexturedRectangles]; if (Level.EngineVersion == TR2VersionType.TombRaider_4) { for (int j = 0; j < Level.Meshes[i].NumTexturedRectangles; j++) { byte[] brectData = meshReader.ReadBytes(Tr2Face4Size); Level.Meshes[i].TexturedRectangles[j] = (Tr2Face4)Cast2Struct(brectData,typeof(Tr2Face4)); meshReader.ReadBytes(2); //read 2 dummy bytes } } else { for (int j = 0; j < Level.Meshes[i].NumTexturedRectangles; j++) { byte[] brectData = meshReader.ReadBytes(Tr2Face4Size); Level.Meshes[i].TexturedRectangles[j] = (Tr2Face4)Cast2Struct(brectData,typeof(Tr2Face4)); //no dummy bytes } } } // get list of textured NumTexturedTriangles Level.Meshes[i].NumTexturedTriangles = meshReader.ReadInt16(); Level.Meshes[i].NumTexturedTriangles = (short) Mathf.Abs(Level.Meshes[i].NumTexturedTriangles); //print("Level.Meshes["+i+"].NumTexturedTriangles " + Level.Meshes[i].NumTexturedTriangles ); if (Level.Meshes[i].NumTexturedTriangles > 0) { Level.Meshes[i].TexturedTriangles = new Tr2Face3[Level.Meshes[i].NumTexturedTriangles ]; if (Level.EngineVersion == TR2VersionType.TombRaider_4) { for (int j = 0; j < Level.Meshes[i].NumTexturedTriangles ; j++) { byte[] btriData = meshReader.ReadBytes(Tr2Face3Size); Level.Meshes[i].TexturedTriangles[j] = (Tr2Face3)Cast2Struct(btriData,typeof(Tr2Face3)); meshReader.ReadBytes(2); //read 2 dummy bytes } } else { for (int j = 0; j < Level.Meshes[i].NumTexturedTriangles; j++) { byte[] btriData = meshReader.ReadBytes(Tr2Face3Size); Level.Meshes[i].TexturedTriangles[j] = (Tr2Face3)Cast2Struct(btriData,typeof(Tr2Face3)); //no dummy bytes } } } // get list of colored rectangles Level.Meshes[i].NumColouredRectangles = meshReader.ReadInt16(); Level.Meshes[i].NumColouredRectangles = (short) Mathf.Abs(Level.Meshes[i].NumColouredRectangles); //print("Level.Meshes["+i+"].NumColouredRectangles " + Level.Meshes[i].NumColouredRectangles); if(Level.Meshes[i].NumColouredRectangles > 0) { Level.Meshes[i].ColouredRectangles = new Tr2Face4[Level.Meshes[i].NumColouredRectangles]; for(int j = 0; j < Level.Meshes[i].NumColouredRectangles; j++) { byte[] brectColorData = meshReader.ReadBytes(Tr2Face4Size); Level.Meshes[i].ColouredRectangles[j] = (Tr2Face4)Cast2Struct(brectColorData,typeof(Tr2Face4)); } } // get list of colored Triangles Level.Meshes[i].NumColouredTriangles = meshReader.ReadInt16(); Level.Meshes[i].NumColouredTriangles = (short) Mathf.Abs(Level.Meshes[i].NumColouredTriangles); //print("Level.Meshes["+i+"].NumColouredTriangles " + Level.Meshes[i].NumColouredTriangles); if(Level.Meshes[i].NumColouredTriangles > 0) { Level.Meshes[i].ColouredTriangles = new Tr2Face3[Level.Meshes[i].NumColouredTriangles]; for(int j = 0; j < Level.Meshes[i].NumColouredTriangles; j++) { byte[] btriColorData = meshReader.ReadBytes(Tr2Face3Size); Level.Meshes[i].ColouredTriangles[j] = (Tr2Face3)Cast2Struct(btriColorData,typeof(Tr2Face3)); } } } //done }
public static Tr2Level Parse(byte[] unzippeddata) { m_Level = new Tr2Level(); MemoryStream ms = new MemoryStream(unzippeddata); BinaryReader br = new BinaryReader(ms); if(System.BitConverter.IsLittleEndian) { //readm_LevelVersion m_Level.Version =br.ReadUInt32(); //print("m_Level.Version " + m_Level.Version ); m_Level.EngineVersion = getTREngineVersionFromVersion(m_Level.Version); //print("m_Level.EngineVersion " +m_Level.EngineVersion ); if (m_Level.EngineVersion != TR2VersionType.TombRaider_2) { return null; } m_Level.Palette8 = new Tr2Colour[256]; m_Level.Palette16 = new uint[256]; for(int colorIdx = 0 ; colorIdx < 256; colorIdx++) { m_Level.Palette8 [colorIdx].Red = br.ReadByte(); m_Level.Palette8 [colorIdx].Green = br.ReadByte(); m_Level.Palette8 [colorIdx].Blue = br.ReadByte(); } for(int colorIdx = 0 ; colorIdx < 256; colorIdx++) { m_Level.Palette16[colorIdx] = br.ReadUInt32(); } //read NumTexTiles m_Level.NumTextiles = br.ReadUInt32();//System.BitConverter.ToUInt32(m_TrLevelData.bytes, sizeof(uint)); //print("m_Level.NumTextiles " + m_Level.NumTextiles ); //Tr2Textile8 m_Level.Textile8 = new Tr2Textile8[m_Level.NumTextiles]; for(int texTilecount = 0 ; texTilecount < m_Level.NumTextiles; texTilecount++) { m_Level.Textile8[texTilecount].Tile = br.ReadBytes(256 * 256); } //Tr2Textile16 m_Level.Textile16 = new Tr2Textile16[m_Level.NumTextiles]; for(int texTilecount = 0 ; texTilecount < m_Level.NumTextiles; texTilecount++) { m_Level.Textile16[texTilecount].Tile = new ushort[256 * 256]; for(uint shortcnt = 0; shortcnt < (256 * 256); shortcnt++) { m_Level.Textile16[texTilecount].Tile[shortcnt] = br.ReadUInt16(); } } m_Level.m_TexWidth = m_Level.m_MaxWidth; m_Level.m_TexHeight = (int)m_Level.NumTextiles * m_Level.m_TexWidth; m_Level.m_MaxTiles = (int)m_Level.NumTextiles; //padTiles = 16 - m_MaxTiles; m_Level.UnknownT = br.ReadUInt32(); //unused m_Level.NumRooms = br.ReadUInt16(); //print("m_Level.NumRooms:"+m_Level.NumRooms); //extract room details m_Level.Rooms = new Tr2Room[m_Level.NumRooms]; for (int i = 0; i < m_Level.NumRooms; ++i) { //print("process room:"+i); //print("-------------:"); //print("-------------:"); //get room global data of length //get room info //m_Level.Rooms[i].info = new Tr2RoomInfo(); byte[] tmpArr = br.ReadBytes(Tr2RoomInfoSize); m_Level.Rooms[i].info =(Tr2RoomInfo) Cast2Struct(tmpArr,typeof(Tr2RoomInfo)); //print("m_Level.Rooms["+i+"].info length" + sizeData); //print("m_Level.Rooms["+i+"].info x z: " + m_Level.Rooms[i].info.x + " " + m_Level.Rooms[i].info.z); m_Level.Rooms[i].NumDataWords = br.ReadUInt32(); int sizeRoomData = sizeof(ushort) * ((int)m_Level.Rooms[i].NumDataWords); m_Level.Rooms[i].Data = br.ReadBytes(sizeRoomData); //print("m_Level.Rooms["+i+"].Data" +System.Buffer.ByteLength(m_Level.Rooms[i].Data)); byte[] dataArr = m_Level.Rooms[i].Data; //variable length data for this room //create a stream reader MemoryStream roomDataStream = new MemoryStream(dataArr); BinaryReader roomReader = new BinaryReader(roomDataStream); //process ushort NumVertices; m_Level.Rooms[i].RoomData.NumVertices = roomReader.ReadInt16(); if(m_Level.Rooms[i].RoomData.NumVertices > 0) { //print("m_Level.Rooms["+i+"].RoomData.NumVertices" +m_Level.Rooms[i].RoomData.NumVertices); m_Level.Rooms[i].RoomData.Vertices = new Tr2VertexRoom[m_Level.Rooms[i].RoomData.NumVertices]; for(int vertAttribCount = 0; vertAttribCount < m_Level.Rooms[i].RoomData.NumVertices; vertAttribCount++) { byte[] bVertData = roomReader.ReadBytes(Tr2VertexRoomSize); m_Level.Rooms[i].RoomData.Vertices[vertAttribCount] = (Tr2VertexRoom) Cast2Struct(bVertData, typeof(Tr2VertexRoom)); //print("m_Level.Rooms["+i+"].RoomData.Vertices"+"["+ vertAttribCount +"]"+".Lighting1 value" + //m_Level.Rooms[i].RoomData.Vertices[vertAttribCount].Lighting1); //DataOffset = DataOffset + (uint) sizeVertex; } } //process NumRectangles m_Level.Rooms[i].RoomData.NumRectangles = roomReader.ReadInt16(); //print("m_Level.Rooms["+i+"].RoomData.NumRectangles" +m_Level.Rooms[i].RoomData.NumRectangles); if(m_Level.Rooms[i].RoomData.NumRectangles > 0) { m_Level.Rooms[i].RoomData.Rectangles = new Tr2Face4[m_Level.Rooms[i].RoomData.NumRectangles]; for(int rectCount = 0; rectCount < m_Level.Rooms[i].RoomData.NumRectangles; rectCount++) { byte[] bVertData = roomReader.ReadBytes(Tr2Face4Size); m_Level.Rooms[i].RoomData.Rectangles[rectCount] = (Tr2Face4)Cast2Struct(bVertData,typeof(Tr2Face4)); } } //process NumTriangles m_Level.Rooms[i].RoomData.NumTriangles = roomReader.ReadInt16(); //print("m_Level.Rooms["+i+"].RoomData.NumTriangles" +m_Level.Rooms[i].RoomData.NumTriangles); if(m_Level.Rooms[i].RoomData.NumTriangles > 0) { m_Level.Rooms[i].RoomData.Triangles = new Tr2Face3[m_Level.Rooms[i].RoomData.NumTriangles]; for(int triCount = 0; triCount < m_Level.Rooms[i].RoomData.NumTriangles; triCount++) { byte[] bVertData = roomReader.ReadBytes(Tr2Face3Size); m_Level.Rooms[i].RoomData.Triangles[triCount] = (Tr2Face3)Cast2Struct(bVertData,typeof(Tr2Face3)); } } //process Numsprites m_Level.Rooms[i].RoomData.Numsprites = roomReader.ReadInt16(); //print("m_Level.Rooms["+i+"].RoomData.Numsprites" +m_Level.Rooms[i].RoomData.Numsprites); if(m_Level.Rooms[i].RoomData.Numsprites > 0) { m_Level.Rooms[i].RoomData.Sprites = new Tr2RoomSprite[m_Level.Rooms[i].RoomData.Numsprites]; for(int spriteCount = 0; spriteCount < m_Level.Rooms[i].RoomData.Numsprites; spriteCount++) { byte[] bVertData = roomReader.ReadBytes(Tr2RoomSpriteSize); m_Level.Rooms[i].RoomData.Sprites[spriteCount] = (Tr2RoomSprite) Cast2Struct(bVertData,typeof(Tr2RoomSprite)); } } //Done: //struct Tr2RoomData //now can free room data m_Level.Rooms[i].NumPortals = br.ReadUInt16(); //print("m_Level.Rooms["+i+"].NumPortals"+ m_Level.Rooms[i].NumPortals); if(m_Level.Rooms[i].NumPortals > 0) { m_Level.Rooms[i].Portals = new Tr2RoomPortal [m_Level.Rooms[i].NumPortals]; for(int portalCount = 0; portalCount < m_Level.Rooms[i].NumPortals; portalCount++) { //public ushort AdjoiningRoom; // which room this "door" leads to 2 bytes //public Tr2Vertex Normal; // which way the "door" faces 6 bytes //public Tr2Vertex[] Vertices; // the 4 corners of the "door" 4 * 6 = 24 byte m_Level.Rooms[i].Portals[portalCount].AdjoiningRoom = br.ReadUInt16(); byte[] dataPortalNormal = br.ReadBytes(Tr2VertexSize); m_Level.Rooms[i].Portals[portalCount].Normal = (Tr2Vertex) Cast2Struct(dataPortalNormal,typeof(Tr2Vertex)); m_Level.Rooms[i].Portals[portalCount].Vertices = new Tr2Vertex[4]; for(int vtxcount = 0; vtxcount < 4 ; vtxcount++) { byte[] dataPortalVertices = br.ReadBytes(Tr2VertexSize); m_Level.Rooms[i].Portals[portalCount].Vertices[vtxcount] = (Tr2Vertex) Cast2Struct(dataPortalVertices,typeof(Tr2Vertex)); } } } // read sector info m_Level.Rooms[i].NumZsectors = br.ReadUInt16(); m_Level.Rooms[i].NumXsectors = br.ReadUInt16(); int numsector = m_Level.Rooms[i].NumZsectors * m_Level.Rooms[i].NumXsectors; //print("m_Level.Rooms["+i+"].NumZsectors:"+ m_Level.Rooms[i].NumZsectors ); //print("m_Level.Rooms["+i+"].NumXsectors:"+ m_Level.Rooms[i].NumXsectors ); if(numsector > 0) { m_Level.Rooms[i].SectorList = new Tr2RoomSector[numsector]; for(int sectorCount = 0 ; sectorCount < numsector; sectorCount++) { byte[] sectorData = br.ReadBytes(Tr2RoomSectorSize); m_Level.Rooms[i].SectorList[sectorCount] = (Tr2RoomSector) Cast2Struct(sectorData, typeof(Tr2RoomSector)); } } //read room lighting & mode //TR2fread(&Level->Rooms[i].Intensity1, 6, 1, m_FP); m_Level.Rooms[i].Intensity1 = br.ReadInt16(); m_Level.Rooms[i].Intensity2 = br.ReadInt16(); m_Level.Rooms[i].LightMode = br.ReadInt16(); //print("Light [TR2|[TR4][Intensity1] [Intensity2] [mode]:" + //m_Level.Rooms[i].Intensity1 + " " + //m_Level.Rooms[i].Intensity2 + " " + //m_Level.Rooms[i].LightMode); // read room lighting info m_Level.Rooms[i].NumLights = br.ReadUInt16(); //print("m_Level.Rooms["+i+"].NumLights:" + (int)m_Level.Rooms[i].NumLights); if (m_Level.Rooms[i].NumLights > 0) { m_Level.Rooms[i].Lights = new Tr2RoomLight[m_Level.Rooms[i].NumLights]; for(int lightCnt = 0; lightCnt < m_Level.Rooms[i].NumLights; lightCnt++) { byte[] lightData = br.ReadBytes(Tr2RoomLightSize); m_Level.Rooms[i].Lights[lightCnt] = (Tr2RoomLight) Cast2Struct(lightData,typeof(Tr2RoomLight)); } } //read Static Mesh Data m_Level.Rooms[i].NumStaticMeshes = br.ReadUInt16(); //print("m_Level.Rooms["+i+"].NumStaticMeshes" + m_Level.Rooms[i].NumStaticMeshes); if (m_Level.Rooms[i].NumStaticMeshes > 0) { m_Level.Rooms[i].StaticMeshes =new Tr2RoomStaticMesh [m_Level.Rooms[i].NumStaticMeshes]; for (int meshCnt = 0; meshCnt < m_Level.Rooms[i].NumStaticMeshes; meshCnt++) { byte[] meshData = br.ReadBytes(Tr2RoomSaticMeshSize); m_Level.Rooms[i].StaticMeshes[meshCnt] = (Tr2RoomStaticMesh) Cast2Struct(meshData,typeof(Tr2RoomStaticMesh)); } } //AlternateRoom settings m_Level.Rooms[i].AlternateRoom = br.ReadInt16(); m_Level.Rooms[i].Flags = br.ReadInt16(); //Done: } } //floor data m_Level.NumFloorData = br.ReadUInt32(); //print("m_Level.NumFloorData"+ m_Level.NumFloorData); if (m_Level.NumFloorData > 0) { m_Level.FloorData = new ushort[m_Level.NumFloorData]; for(int floorDataCnt = 0; floorDataCnt < m_Level.NumFloorData; floorDataCnt++) { m_Level.FloorData[floorDataCnt] = br.ReadUInt16(); } } uint NumMeshDataWords; byte[] RawMeshData = null;; int dataSize = 0; NumMeshDataWords = br.ReadUInt32(); if(NumMeshDataWords > 0) { dataSize = (int)(2 * NumMeshDataWords); RawMeshData = br.ReadBytes(dataSize); } m_Level.NumMeshPointers =br.ReadUInt32(); if(m_Level.NumMeshPointers > 0) { m_Level.MeshPointerList = new uint[m_Level.NumMeshPointers]; for(int ptrCount = 0; ptrCount < m_Level.NumMeshPointers; ptrCount++) { m_Level.MeshPointerList[ptrCount] = br.ReadUInt32(); } } ExtractMeshes(m_Level,RawMeshData, m_Level.NumMeshPointers, m_Level.MeshPointerList); //read animation data m_Level.NumAnimations = br.ReadUInt32(); //print("m_Level.NumAnimations:" + m_Level.NumAnimations); if (m_Level.NumAnimations > 0) { m_Level.Animations = new Tr2Animation[m_Level.NumAnimations]; for(int animCnt = 0; animCnt < m_Level.NumAnimations; animCnt++) { byte[] animData = br.ReadBytes(Tr2AnimationSize); m_Level.Animations[animCnt] = (Tr2Animation) Cast2Struct(animData, typeof(Tr2Animation)); //print("m_Level.Animations["+animCnt+"].FrameOffset" +m_Level.Animations[animCnt].FrameOffset); //print("m_Level.Animations["+animCnt+"].FrameRate" + m_Level.Animations[animCnt].FrameRate); //print("m_Level.Animations["+animCnt+"].FrameSize" + m_Level.Animations[animCnt].FrameSize); } } //read state changes m_Level.NumStateChanges = br.ReadUInt32(); if (m_Level.NumStateChanges > 0) { m_Level.StateChanges = new Tr2StateChange[m_Level.NumStateChanges]; for(int stateChangeCount = 0; stateChangeCount <m_Level.NumStateChanges;stateChangeCount++) { byte[] state_change_data = br.ReadBytes(Tr2StateChangeSize); m_Level.StateChanges[stateChangeCount] = (Tr2StateChange) Cast2Struct(state_change_data,typeof(Tr2StateChange)); //print("m_Level.StateChanges["+stateChangeCount+"].StateID"+ m_Level.StateChanges[stateChangeCount] .StateID); } } //read AnimDispatches m_Level.NumAnimDispatches = br.ReadUInt32(); //print("m_Level.NumAnimDispatches:"+ m_Level.NumAnimDispatches); if ( m_Level.NumAnimDispatches > 0) { m_Level.AnimDispatches = new Tr2AnimDispatch[m_Level.NumAnimDispatches]; for(int animDispatchCount = 0; animDispatchCount < m_Level.NumAnimDispatches;animDispatchCount++) { byte[] anim_dispatch_data = br.ReadBytes(Tr2AnimDispatchSize); m_Level.AnimDispatches[animDispatchCount] = (Tr2AnimDispatch) Cast2Struct(anim_dispatch_data,typeof(Tr2AnimDispatch)); } } //read anim commands m_Level.NumAnimCommands = br.ReadUInt32(); //print("m_Level.NumAnimCommands" + m_Level.NumAnimCommands); if (m_Level.NumAnimCommands > 0) { m_Level.AnimCommands = new Tr2AnimCommand[m_Level.NumAnimCommands]; for(int animCommandCount = 0; animCommandCount < m_Level.NumAnimCommands; animCommandCount++) { byte[] anim_command_data = br.ReadBytes(Tr2AnimCommandSize); m_Level.AnimCommands[animCommandCount] = (Tr2AnimCommand) Cast2Struct(anim_command_data,typeof(Tr2AnimCommand)); } } // read MeshTrees m_Level.NumMeshTrees = br.ReadUInt32(); //total number of ints, not Tr2MeshTree //print("m_Level.NumMeshTrees" + m_Level.NumMeshTrees); //int numMeshTreeStruct = (int)(m_Level.NumMeshTrees / sizeTr2MeshTree); //print("numMeshTreeStruct" + numMeshTreeStruct); if ( m_Level.NumMeshTrees > 0) { m_Level.MeshTrees = new int[m_Level.NumMeshTrees]; //read as int for(int meshtreecnt =0 ; meshtreecnt < m_Level.NumMeshTrees; meshtreecnt++) { m_Level.MeshTrees [meshtreecnt] = br.ReadInt32(); } } // read frames m_Level.NumFrames = br.ReadUInt32(); //print( "m_Level.NumFrames" + m_Level.NumFrames); if (m_Level.NumFrames > 0) { m_Level.Frames = new ushort[m_Level.NumFrames]; for(int frmCount = 0; frmCount < m_Level.NumFrames;frmCount++) { m_Level.Frames[frmCount] = br.ReadUInt16(); } } // read moveables m_Level.NumMoveables = br.ReadUInt32(); //print("m_Level.NumMoveables" + m_Level.NumMoveables); if (m_Level.NumMoveables > 0) { m_Level.Moveables = new Tr2Moveable[m_Level.NumMoveables]; for(int movableCount = 0; movableCount < m_Level.NumMoveables; movableCount++) { byte[] moveable_item_data = br.ReadBytes(Tr2MoveableSize); m_Level.Moveables[movableCount] = (Tr2Moveable) Cast2Struct(moveable_item_data,typeof(Tr2Moveable)); } } //read static mesh m_Level.NumStaticMeshes = br.ReadUInt32(); if (m_Level.NumStaticMeshes > 0) { m_Level.StaticMeshes = new Tr2StaticMesh[m_Level.NumStaticMeshes]; for(int staticMeshCount = 0; staticMeshCount < m_Level.NumStaticMeshes;staticMeshCount++) { m_Level.StaticMeshes[staticMeshCount].BoundingBox = new Tr2Vertex[4]; m_Level.StaticMeshes[staticMeshCount].ObjectID = br.ReadUInt32(); m_Level.StaticMeshes[staticMeshCount].StartingMesh = br.ReadUInt16(); for(int boundingBoxCount = 0;boundingBoxCount < 4;boundingBoxCount++) { byte[] staticBoxData = br.ReadBytes(Tr2VertexSize); m_Level.StaticMeshes[staticMeshCount].BoundingBox[boundingBoxCount] = (Tr2Vertex) Cast2Struct(staticBoxData,typeof(Tr2Vertex)); } m_Level.StaticMeshes[staticMeshCount].Flags = br.ReadUInt16(); //print("m_Level.StaticMeshes["+staticMeshCount+"].ObjectID " + m_Level.StaticMeshes[staticMeshCount].ObjectID); } } // read object textures m_Level.NumObjectTextures = br.ReadUInt32(); //print("m_Level.NumObjectTextures:"+ m_Level.NumObjectTextures); if (m_Level.NumObjectTextures > 0) { m_Level.ObjectTextures = new Tr2ObjectTexture[m_Level.NumObjectTextures]; for(int objTexCount = 0; objTexCount < m_Level.NumObjectTextures; objTexCount++) { m_Level.ObjectTextures[objTexCount].Vertices = new Tr2ObjectTextureVertex[4]; m_Level.ObjectTextures[objTexCount].TransparencyFlags = br.ReadUInt16(); m_Level.ObjectTextures[objTexCount].Tile = br.ReadUInt16(); for(int vtxcount = 0 ; vtxcount < 4; vtxcount++) { byte[] object_texture_vert_data = br.ReadBytes(Tr2ObjectTextureVertSize); m_Level.ObjectTextures[objTexCount].Vertices[vtxcount] = (Tr2ObjectTextureVertex) Cast2Struct(object_texture_vert_data, typeof(Tr2ObjectTextureVertex)); } } } //read sprite textures m_Level.NumspriteTextures = br.ReadUInt32(); //print("m_Level.NumspriteTextures"+ m_Level.NumspriteTextures); if (m_Level.NumspriteTextures > 0) { m_Level.SpriteTextures = new Tr2SpriteTexture[m_Level.NumspriteTextures]; for(int spriteTexCount = 0; spriteTexCount < m_Level.NumspriteTextures; spriteTexCount++) { byte[] spriteTexData = br.ReadBytes(Tr2SpriteTextureSize); m_Level.SpriteTextures[spriteTexCount] = (Tr2SpriteTexture) Cast2Struct(spriteTexData, typeof(Tr2SpriteTexture)); } } //read sprite texture data m_Level.NumSpriteSequences = br.ReadUInt32(); //print("m_Level.NumSpriteSequences"+ m_Level.NumSpriteSequences); if (m_Level.NumSpriteSequences > 0) { m_Level.SpriteSequences = new Tr2SpriteSequence[m_Level.NumSpriteSequences]; for(int spriteSeqCount = 0; spriteSeqCount < m_Level.NumSpriteSequences; spriteSeqCount++) { byte[] spriteSeqData = br.ReadBytes(Tr2SpriteSequenceSize); m_Level.SpriteSequences[spriteSeqCount] = (Tr2SpriteSequence) Cast2Struct(spriteSeqData,typeof(Tr2SpriteSequence)); } } //read cameras m_Level.NumCameras = br.ReadInt32(); //print("m_Level.NumCameras"+ m_Level.NumCameras); if (m_Level.NumCameras > 0) { m_Level.Cameras = new Tr2Camera[m_Level.NumCameras]; for(int camCount = 0 ; camCount <m_Level.NumCameras; camCount++) { byte[] camData = br.ReadBytes(Tr2CameraSize); m_Level.Cameras[camCount] = (Tr2Camera) Cast2Struct(camData,typeof(Tr2Camera)); } } // read sound effects m_Level.NumsoundSources = br.ReadInt32(); //print("m_Level.NumsoundSources" + m_Level.NumsoundSources); if (m_Level.NumsoundSources > 0) { m_Level.SoundSources = new Tr2SoundSource[m_Level.NumsoundSources]; for(int soundSrcCount = 0; soundSrcCount < m_Level.NumsoundSources; soundSrcCount++) { byte[] sndSrcData = br.ReadBytes(Tr2SoundSourceSize); m_Level.SoundSources[soundSrcCount] = (Tr2SoundSource) Cast2Struct(sndSrcData,typeof(Tr2SoundSource)); //print("m_Level.SoundSources[soundSrcCount] x y z" + m_Level.SoundSources[soundSrcCount].x); } } //read boxes m_Level.NumBoxes = br.ReadInt32(); //print("m_Level.NumBoxes:"+ m_Level.NumBoxes); if (m_Level.NumBoxes > 0) { m_Level.Boxes = new Tr2BBox[m_Level.NumBoxes]; //load tr2box data for( int tr2BoxCount = 0; tr2BoxCount <m_Level.NumBoxes; tr2BoxCount++) { byte[] tr2_boxData = br.ReadBytes(Tr2BBoxSize); m_Level.Boxes[tr2BoxCount] = (Tr2BBox) Cast2Struct(tr2_boxData,typeof(Tr2BBox)); } } //read overlaps m_Level.NumOverlaps =br.ReadInt32(); //print("m_Level.NumOverlaps" + m_Level.NumOverlaps); if (m_Level.NumOverlaps > 0) { m_Level.Overlaps = new short[m_Level.NumOverlaps ]; for(int overlapCnt = 0; overlapCnt < m_Level.NumOverlaps;overlapCnt++) { m_Level.Overlaps[overlapCnt] = br.ReadInt16(); } } //read Zones if (m_Level.NumBoxes > 0) { m_Level.Zones = new short[10 * m_Level.NumBoxes]; //10 shorts == 20 byte int sizeZones = 10 * m_Level.NumBoxes; for( int zoneCount = 0; zoneCount < sizeZones; zoneCount++) { m_Level.Zones[zoneCount] = br.ReadInt16(); } } //read animation textures m_Level.NumAnimatedTextures = br.ReadInt32(); if (m_Level.NumAnimatedTextures > 0) { m_Level.AnimatedTextures = new short[m_Level.NumAnimatedTextures]; for( int animTexCount = 0; animTexCount < m_Level.NumAnimatedTextures ; animTexCount++) { m_Level.AnimatedTextures[animTexCount] = br.ReadInt16(); } } //08-09-2011 //read items m_Level.NumItems = br.ReadInt32(); if(m_Level.NumItems > 0) { m_Level.Items = new Tr2Item[m_Level.NumItems]; for (int trItemCount = 0; trItemCount < m_Level.NumItems ; trItemCount++) { byte[] tr_itemData = br.ReadBytes(Tr2ItemSize); m_Level.Items[trItemCount] = (Tr2Item) Cast2Struct(tr_itemData,typeof(Tr2Item)); } } //read LightMaps int numLightMapData = 32 * 256; m_Level.LightMap = new byte[numLightMapData]; for(int byteCnt = 0; byteCnt < numLightMapData; byteCnt++) { m_Level.LightMap[byteCnt] = br.ReadByte(); } //read cinematic frames m_Level.NumCinematicFrames = br.ReadUInt16(); if (m_Level.NumCinematicFrames > 0) { m_Level.CinematicFrames = new Tr2CinematicFrame[m_Level.NumCinematicFrames]; for(int frameCount = 0; frameCount < m_Level.NumCinematicFrames; frameCount++) { byte[] tr_cenematic_data = br.ReadBytes(Tr2CinematicFrameSize); m_Level.CinematicFrames[frameCount] = (Tr2CinematicFrame) Cast2Struct(tr_cenematic_data, typeof(Tr2CinematicFrame)); } } //read demodata m_Level.NumDemoData = br.ReadInt16(); if (m_Level.NumDemoData > 0) { m_Level.DemoData = new byte[m_Level.NumDemoData]; m_Level.DemoData = br.ReadBytes(m_Level.NumDemoData); } return m_Level; }