private void ReadSceneryInstances(BinaryReader br, uint size) { size -= BinaryUtil.AlignReader(br, 0x10); Debug.Assert(size % 0x40 == 0); var count = (int)size / 0x40; _scenerySection.Instances = new List <SceneryInstance>(count); for (int i = 0; i < count; ++i) { var instance = new SceneryInstance(); var internalInstance = BinaryUtil.ReadUnmanagedStruct <SceneryInstanceInternal>(br); instance.InfoIndex = internalInstance.SceneryInfoNumber; instance.Transform = Matrix4x4.Multiply(internalInstance.Rotation, Matrix4x4.CreateTranslation(internalInstance.Position)); _scenerySection.Instances.Add(instance); } }
protected override void ReadChunks(BinaryReader br, uint containerSize) { var endPos = br.BaseStream.Position + containerSize; while (br.BaseStream.Position < endPos) { var chunkId = br.ReadUInt32(); var chunkSize = br.ReadUInt32(); var chunkEndPos = br.BaseStream.Position + chunkSize; if ((chunkId & 0x80000000) == 0x80000000) { ReadChunks(br, chunkSize); } else { switch (chunkId) { case InfoChunkId: { _texturePack.Version = br.ReadUInt32(); _texturePack.Name = new string(br.ReadChars(28)).Trim('\0'); _texturePack.PipelinePath = new string(br.ReadChars(64)).Trim('\0'); _texturePack.Hash = br.ReadUInt32(); break; } case 0x33310003: { _compressed = true; Debug.Assert(chunkSize % Marshal.SizeOf <DataOffsetStruct>() == 0, "chunkSize % Marshal.SizeOf<DataOffsetStruct>() == 0"); while (br.BaseStream.Position < chunkEndPos) { var dos = br.GetStruct <DataOffsetStruct>(); var curPos = br.BaseStream.Position; br.BaseStream.Position = dos.Offset; ReadCompressedData(br, dos); br.BaseStream.Position = curPos; } break; } case TexChunkId: { var textureStructSize = Marshal.SizeOf <TextureStruct>(); Debug.Assert(chunkSize % textureStructSize == 0); var numTextures = chunkSize / textureStructSize; for (var j = 0; j < numTextures; j++) { ReadTexture(br); } break; } case TexDataChunkId: { if (!_compressed) { BinaryUtil.AlignReader(br, 0x80); var basePos = br.BaseStream.Position; foreach (var t in _texturePack.Textures) { br.BaseStream.Position = basePos + t.DataOffset; t.Data = new byte[t.DataSize]; br.Read(t.Data, 0, t.Data.Length); if (t.PaletteSize > 0) { br.BaseStream.Position = basePos + t.PaletteOffset; t.Palette = new byte[t.PaletteSize]; br.Read(t.Palette, 0, t.Palette.Length); } } } break; } case DDSChunkId: { foreach (var t in _texturePack.Textures) { br.BaseStream.Seek(20, SeekOrigin.Current); t.Format = br.ReadUInt32(); //Console.WriteLine($"{t.Name} = 0x{((int)t.Format):X8}"); br.BaseStream.Seek(0x08, SeekOrigin.Current); } break; } } } br.BaseStream.Position = chunkEndPos; } }