private VpuPacket(Stream stream) { var vpu = BinaryMapping.ReadObject <VpuHeader>(stream); VertexRange = Read(stream, vpu.UnkBoxLocation, vpu.UnkBoxCount, ReadInt32); Indices = Read(stream, vpu.IndexLocation, vpu.IndexCount, ReadIndex); Colors = Read(stream, vpu.ColorLocation, vpu.ColorCount, ReadColor); Vertices = Read(stream, vpu.VertexLocation, vpu.VertexCount, ReadVertex); if (vpu.VertexMixerCount > 0) { var countPerAmount = Read(stream, vpu.VertexMixerOffset, vpu.VertexMixerCount, ReadInt32); VertexWeightedCount = countPerAmount.Sum(); VertexWeightedIndices = countPerAmount .Select((count, amount) => { stream.AlignPosition(0x10); return(Enumerable .Range(0, count) .Select(x => Enumerable.Range(0, amount + 1).Select(y => stream.ReadInt32()).ToArray()) .ToArray()); }) .ToArray(); } //Debug.Assert(vpu.VertexCount == Box.Sum()); }
public void Write(Stream stream) { var entries = new List <Entry>(8); AddEntry(entries, HeaderSize, 1); AddEntry(entries, CollisionMeshGroupList.Count * Col1Size, 0x10); AddEntry(entries, CollisionMeshList.Count * Col2Size, 0x10); AddEntry(entries, CollisionList.Count * Col3Size, 4); AddEntry(entries, VertexList.Count * Col4Size, 0x10); AddEntry(entries, PlaneList.Count * Col5Size, 0x10); AddEntry(entries, BoundingBoxList.Count * Col6Size, 0x10); AddEntry(entries, SurfaceFlagsList.Count * Col7Size, 4); stream.Position = 0; BinaryMapping.WriteObject(stream, new Header { MagicCode = MagicCode, Version = 1, Unknown08 = Unknown08, Unknown0c = Unknown0c, Entries = entries.ToArray() }); WriteCoctEntry(stream, CollisionMeshGroupList); WriteCoctEntry(stream, CollisionMeshList); WriteCoctEntry(stream, CollisionList); stream.AlignPosition(0x10); WriteValueEntry(stream, VertexList, WriteVector4); WriteValueEntry(stream, PlaneList, WritePlane); WriteValueEntry(stream, BoundingBoxList, WriteBoundingBoxInt16); WriteCoctEntry(stream, SurfaceFlagsList); }
public static void WriteAsFac(Stream stream, IEnumerable <Imgd> images) { foreach (var image in images) { image.Write(stream); stream.SetLength(stream.AlignPosition(FacAlignment).Position); } }
public byte[] ReadRawRemasteredAsset(string assetName) { var entry = _entries[assetName]; var data = new byte[entry.CompressedLength >= 0 ? entry.CompressedLength : entry.DecompressedLength]; data = _stream.AlignPosition(0x10).ReadBytes(data.Length); return(data); }
private static void WriteSubModel(Stream stream, SubModel subModel, int baseAddress) { var header = new SubModelHeader { Type = subModel.Type, Unk04 = subModel.Unk04, Unk08 = subModel.Unk08, Unk = subModel.Unk, DmaChainCount = subModel.DmaChains.Count, }; stream.Position += 0x20; // skip header stream.Position += subModel.DmaChainCount * 0x20; if (subModel.Type == Entity) { header.UnkDataOffset = (int)stream.Position; stream.Write(subModel.UnknownData); header.BoneOffset = (int)stream.Position; header.BoneCount = (short)subModel.Bones.Count; foreach (var bone in subModel.Bones) { WriteBone(stream, bone); } } else if (subModel.Type == Shadow) { header.UnkDataOffset = 0; header.BoneOffset = 0; header.BoneCount = subModel.BoneCount; } else { throw new NotImplementedException($"Submodel type {subModel.Type} not supported."); } var dmaChainHeaders = subModel.DmaChains.Select(x => WriteDmaChain(stream, x)).ToList(); stream.SetLength(stream.AlignPosition(0x80).Position); header.NextOffset = baseAddress >= 0 ? (int)(baseAddress + stream.Position) : 0; stream.Position = 0; BinaryMapping.WriteObject(stream, header); foreach (var dmaChainHeader in dmaChainHeaders) { BinaryMapping.WriteObject(stream, dmaChainHeader); } }
public static IEnumerable <Imgd> ReadAsFac(Stream stream) { stream.SetPosition(0); while (true) { stream.AlignPosition(FacAlignment); var subStreamLength = stream.Length - stream.Position; if (subStreamLength < HeaderLength) { yield break; } yield return(Imgd.Read(new SubStream(stream, stream.Position, subStreamLength))); } }
public static void Write(Stream stream, IEnumerable <IEventEntry> eventSet) { foreach (var item in eventSet) { var startPosition = stream.Position; stream.Position += 4; Mapping.WriteObject(stream, item); var nextPosition = stream.AlignPosition(2).Position; var id = _typeId[item.GetType()]; var length = stream.Position - startPosition; stream.Position = startPosition; stream.Write((short)(length)); stream.Write((short)id); stream.Position = nextPosition; } stream.Write(Terminator); }
public static void Write(Stream stream, ICollection <byte[]> entries) { stream.MustWriteAndSeek(); stream.Write(entries.Count); var accumulator = (entries.Count + 2) * 4; foreach (var entry in entries) { accumulator = Helpers.Align(accumulator, Alignment); stream.Write(accumulator); accumulator += entry.Length; } stream.Write(Helpers.Align(accumulator, Alignment)); foreach (var entry in entries) { stream.AlignPosition(Alignment); stream.Write(entry); } }
public static void Write <TStream>(Stream stream, ICollection <TStream> entries) where TStream : Stream { stream.MustWriteAndSeek(); stream.Write(entries.Count); var accumulator = (entries.Count + 2) * 4; foreach (var entry in entries) { accumulator = Helpers.Align(accumulator, Alignment); stream.Write(accumulator); accumulator += (int)stream.Length; } stream.Write(Helpers.Align(accumulator, Alignment)); foreach (var entry in entries) { stream.AlignPosition(Alignment); entry.FromBegin().CopyTo(stream); } }
private byte[] ReadRemasteredAsset(string assetName) { var header = _entries[assetName]; var dataLength = header.CompressedLength >= 0 ? header.CompressedLength : header.DecompressedLength; if (dataLength % 16 != 0) { dataLength += 16 - (dataLength % 16); } var data = _stream.AlignPosition(0x10).ReadBytes(dataLength); _remasteredAssetsRawData.Add(assetName, data.ToArray()); if (header.CompressedLength > -2) { for (var i = 0; i < Math.Min(dataLength, 0x100); i += 0x10) { EgsEncryption.DecryptChunk(_key, data, i, PASS_COUNT); } } if (header.CompressedLength > -1) { using var compressedStream = new MemoryStream(data); using var deflate = new DeflateStream(compressedStream.SetPosition(2), CompressionMode.Decompress); var decompressedData = new byte[header.DecompressedLength]; deflate.Read(decompressedData, 0, decompressedData.Length); data = decompressedData; } _remasteredAssetsData.Add(assetName, data.ToArray()); return(data); }
public static void Write(this IEnumerable <Entry> entries, Stream stream) { var myEntries = entries.ToArray(); stream.Position = 0; BinaryMapping.WriteObject(stream, new Header { MagicCode = MagicCode, Version = Version, EntryCount = (short)myEntries.Length, Unused08 = 0, Unused0c = 0 }); var dataStartOffset = (int)stream.Position + myEntries.Length * MetaEntrySize; foreach (var entry in myEntries) { BinaryMapping.WriteObject(stream, new MetaEntry { DirectoryPointer = entry.DirectoryPointer, Offset = entry.IsLink ? 0 : dataStartOffset, Length = entry.IsLink ? 0 : entry.Data.Length, Unused = 0, Name = entry.Name }); dataStartOffset += Helpers.Align(entry.Data?.Length ?? 0, Alignment); } foreach (var entry in myEntries.Where(x => !x.IsLink)) { stream.Write(entry.Data, 0, entry.Data.Length); stream.AlignPosition(Alignment); } }
private static void WriteAsMap(Stream stream, M4 mapModel) { var mapHeader = new SubModelMapHeader { Type = Map, DmaChainMapCount = mapModel.VifPackets.Count, Unk04 = mapModel.unk04, Unk08 = mapModel.unk08, NextOffset = mapModel.nextOffset, va4 = mapModel.va4, CountVifPacketRenderingGroup = Convert.ToInt16(mapModel.vifPacketRenderingGroup.Count), }; BinaryMapping.WriteObject(stream, mapHeader); var dmaChainMapDescriptorOffset = (int)stream.Position; stream.Position += mapModel.VifPackets.Count * 0x10; mapHeader.OffsetVifPacketRenderingGroup = (int)stream.Position; stream.Position += mapModel.vifPacketRenderingGroup.Count * 4; var groupOffsets = new List <int>(); foreach (var group in mapModel.vifPacketRenderingGroup) { groupOffsets.Add((int)stream.Position); WriteUInt16List(stream, group); } // capture remapTable offset here var remapTableOffsetToOffset = Helpers.Align((int)stream.Position, 4); // seek back and fill offsets stream.Position = mapHeader.OffsetVifPacketRenderingGroup; foreach (var offset in groupOffsets) { stream.Write(offset); } // write remapTable here stream.Position = remapTableOffsetToOffset; mapHeader.OffsetToOffsetDmaChainIndexRemapTable = remapTableOffsetToOffset; var remapTableOffset = remapTableOffsetToOffset + 4; stream.Write(remapTableOffset); WriteUInt16List(stream, mapModel.DmaChainIndexRemapTable); stream.AlignPosition(0x10); var dmaChainVifOffsets = new List <int>(); foreach (var dmaChainMap in mapModel.VifPackets) { var vifPacketIndex = 0; dmaChainVifOffsets.Add((int)stream.Position); foreach (var packetCount in dmaChainMap.DmaPerVif) { BinaryMapping.WriteObject(stream, new DmaTag { Qwc = packetCount, Address = 0, TagId = packetCount > 0 ? 1 : 6, Irq = false, }); var packetLength = packetCount * 0x10 + 8; stream.Write(dmaChainMap.VifPacket, vifPacketIndex, packetLength); vifPacketIndex += packetLength; } } stream.AlignPosition(0x80); stream.SetLength(stream.Position); stream.Position = dmaChainMapDescriptorOffset; for (var i = 0; i < mapModel.VifPackets.Count; i++) { var dmaChainMap = mapModel.VifPackets[i]; BinaryMapping.WriteObject(stream, new DmaChainMap { VifOffset = dmaChainVifOffsets[i], TextureIndex = dmaChainMap.TextureId, Unk08 = dmaChainMap.Unk08, Unk0a = dmaChainMap.IsTransparentFlag, Unk0c = dmaChainMap.Unk0c }); } stream.Position = 0; BinaryMapping.WriteObject(stream, mapHeader); }
private static DmaChainHeader WriteDmaChain(Stream stream, DmaChain dmaChain) { var dmaChainHeader = new DmaChainHeader { Unk00 = dmaChain.Unk00, TextureIndex = dmaChain.TextureIndex, Unk08 = dmaChain.Unk08, DmaLength = dmaChain.DmaLength, }; var dmaVifs = dmaChain.DmaVifs; var vifPacketOffsets = new List <int>(); foreach (var dmaVif in dmaVifs) { vifPacketOffsets.Add((int)stream.Position); stream.Write(dmaVif.VifPacket); } dmaChainHeader.DmaOffset = (int)stream.Position; for (var i = 0; i < dmaVifs.Count; i++) { if (dmaVifs[i].BaseAddress > 0) { BinaryMapping.WriteObject(stream, new DmaPacket { DmaTag = new DmaTag { Qwc = (ushort)(dmaVifs[i].VifPacket.Length / 0x10), TagId = 3, Irq = false, Address = vifPacketOffsets[i] }, VifCode = new VifCode { }, Parameter = 0 }); for (var j = 0; j < dmaVifs[i].Alaxi.Length; j++) { BinaryMapping.WriteObject(stream, new DmaPacket { DmaTag = new DmaTag { Qwc = 4, TagId = 3, Irq = false, Address = dmaVifs[i].Alaxi[j] }, VifCode = DefaultVifCode, Parameter = dmaVifs[i].BaseAddress + j * 4 }); } } BinaryMapping.WriteObject(stream, CloseDmaPacket); } var alv1 = new List <int>(); foreach (var vif in dmaVifs) { alv1.AddRange(vif.Alaxi); alv1.Add(-1); } alv1.RemoveAt(alv1.Count - 1); dmaChainHeader.Count1aOffset = (int)stream.Position; stream.Write(alv1.Count); foreach (var alvItem in alv1) { stream.Write(alvItem); } stream.AlignPosition(0x10); return(dmaChainHeader); }
private static void WriteAsMap(Stream stream, M4 mapModel) { var mapHeader = new SubModelMapHeader { Type = Map, DmaChainMapCount = mapModel.VifPackets.Count, Unk04 = mapModel.unk04, Unk08 = mapModel.unk08, NextOffset = mapModel.nextOffset, va4 = mapModel.va4, Count1 = mapModel.count1, // in a form, ignored by the game engine }; BinaryMapping.WriteObject(stream, mapHeader); var dmaChainMapDescriptorOffset = (int)stream.Position; stream.Position += mapModel.VifPackets.Count * 0x10; mapHeader.Offset1 = (int)stream.Position; stream.Position += mapModel.alb2.Count * 4; var alb2Offsets = new List <int>(); foreach (var alb2 in mapModel.alb2) { alb2Offsets.Add((int)stream.Position); WriteAlb2(stream, alb2); } var endAlb2Offset = Helpers.Align((int)stream.Position, 4); stream.Position = mapHeader.Offset1; foreach (var alb2Offset in alb2Offsets) { stream.Write(alb2Offset); } stream.Position = endAlb2Offset; mapHeader.Offset2 = endAlb2Offset; stream.Write(endAlb2Offset + 4 + mapModel.unknownTable.Length * 4); stream.Write(mapModel.unknownTable); WriteAlb2(stream, mapModel.alb1t2); stream.AlignPosition(0x10); var dmaChainVifOffsets = new List <int>(); foreach (var dmaChainMap in mapModel.VifPackets) { var vifPacketIndex = 0; dmaChainVifOffsets.Add((int)stream.Position); foreach (var packetCount in dmaChainMap.DmaPerVif) { BinaryMapping.WriteObject(stream, new DmaTag { Qwc = packetCount, Address = 0, TagId = packetCount > 0 ? 1 : 6, Irq = false, }); var packetLength = packetCount * 0x10 + 8; stream.Write(dmaChainMap.VifPacket, vifPacketIndex, packetLength); vifPacketIndex += packetLength; } } stream.AlignPosition(0x80); stream.SetLength(stream.Position); stream.Position = dmaChainMapDescriptorOffset; for (var i = 0; i < mapModel.VifPackets.Count; i++) { var dmaChainMap = mapModel.VifPackets[i]; BinaryMapping.WriteObject(stream, new DmaChainMap { VifOffset = dmaChainVifOffsets[i], TextureIndex = dmaChainMap.TextureId, Unk08 = dmaChainMap.Unk08, Unk0c = dmaChainMap.Unk0c }); } stream.Position = 0; BinaryMapping.WriteObject(stream, mapHeader); }
public void Write(Stream stream) { var collisionList = new List <Collision>(); var collisionMeshList = new List <RawCollisionMesh>(); var collisionMeshGroupList = new List <RawCollisionMeshGroup>(); foreach (var node in CollisionMeshGroupList) { var start = node.Meshes.Count > 0 ? collisionMeshList.Count : 0; collisionMeshGroupList.Add(new RawCollisionMeshGroup { Child1 = node.Child1, Child2 = node.Child2, Child3 = node.Child3, Child4 = node.Child4, Child5 = node.Child5, Child6 = node.Child6, Child7 = node.Child7, Child8 = node.Child8, BoundingBox = node.BoundingBox, CollisionMeshStart = (ushort)start, CollisionMeshEnd = (ushort)(start + node.Meshes.Count) }); foreach (var mesh in node.Meshes) { collisionMeshList.Add(new RawCollisionMesh { BoundingBox = mesh.BoundingBox, CollisionStart = (ushort)collisionList.Count, CollisionEnd = (ushort)(collisionList.Count + mesh.Collisions.Count), v10 = mesh.v10, v12 = mesh.v12 }); collisionList.AddRange(mesh.Collisions); } } var bbCache = new WriteCache <BoundingBoxInt16, string>(x => x.ToString()); bbCache.AddConstant(BoundingBoxInt16.Invalid, -1); foreach (var item in collisionList) { bbCache.Add(item.BoundingBox); } var surfaceCache = new WriteCache <SurfaceFlags, int>(x => x.Flags); foreach (var item in collisionList) { surfaceCache.Add(item.SurfaceFlags); } var planeCache = new WriteCache <Plane, string>(x => x.ToString()); foreach (var item in collisionList) { planeCache.Add(item.Plane); } var entries = new List <Entry>(8); AddEntry(entries, HeaderSize, 1); AddEntry(entries, CollisionMeshGroupList.Count * Col1Size, 0x10); AddEntry(entries, collisionMeshList.Count * Col2Size, 0x10); AddEntry(entries, collisionList.Count * Col3Size, 4); AddEntry(entries, VertexList.Count * Col4Size, 0x10); AddEntry(entries, planeCache.Count * Col5Size, 0x10); AddEntry(entries, bbCache.Count * BoundingBoxSize, 0x10); AddEntry(entries, surfaceCache.Count * Col7Size, 4); stream.Position = 0; BinaryMapping.WriteObject(stream, new Header { MagicCode = MagicCode, Version = 1, Unknown08 = Unknown08, Unknown0c = Unknown0c, Entries = entries.ToArray() }); WriteCoctEntry(stream, collisionMeshGroupList); WriteCoctEntry(stream, collisionMeshList); WriteCoctEntry(stream, collisionList .Select(x => new RawCollision { v00 = x.v00, Vertex1 = x.Vertex1, Vertex2 = x.Vertex2, Vertex3 = x.Vertex3, Vertex4 = x.Vertex4, PlaneIndex = planeCache[x.Plane], BoundingBoxIndex = bbCache[x.BoundingBox], SurfaceFlagsIndex = surfaceCache[x.SurfaceFlags], })); stream.AlignPosition(0x10); WriteValueEntry(stream, VertexList, WriteVector4); WriteValueEntry(stream, planeCache, WritePlane); WriteValueEntry(stream, bbCache, WriteBoundingBoxInt16); WriteCoctEntry(stream, surfaceCache); }
private static void Write(Stream stream, InterpolatedMotion motion, bool unkFlag) { var valuePool = new PoolValues <float>(); var keyFramePool = new PoolValues <float>(motion.Timeline.Select(x => x.KeyFrame).Distinct().OrderBy(x => x)); var tangentPool = new PoolValues <float>(); var rawTimeline = new List <TimelineTableInternal>(motion.Timeline.Count); foreach (var item in motion.Timeline) { rawTimeline.Add(new TimelineTableInternal { Time = (short)(((int)item.Interpolation & 3) | (keyFramePool.GetIndex(item.KeyFrame) << 2)), ValueIndex = (short)valuePool.GetIndex(item.Value), TangentIndexEaseIn = (short)tangentPool.GetIndex(item.TangentEaseIn), TangentIndexEaseOut = (short)tangentPool.GetIndex(item.TangentEaseOut), }); } var writer = new BinaryWriter(stream); var header = new InterpolatedMotionInternal { BoneCount = motion.BoneCount, TotalFrameCount = motion.TotalFrameCount, Unk48 = motion.Unk48, BoundingBoxMinX = motion.BoundingBoxMinX, BoundingBoxMinY = motion.BoundingBoxMinY, BoundingBoxMinZ = motion.BoundingBoxMinZ, BoundingBoxMinW = motion.BoundingBoxMinW, BoundingBoxMaxX = motion.BoundingBoxMaxX, BoundingBoxMaxY = motion.BoundingBoxMaxY, BoundingBoxMaxZ = motion.BoundingBoxMaxZ, BoundingBoxMaxW = motion.BoundingBoxMaxW, FrameLoop = motion.FrameLoop, FrameEnd = motion.FrameEnd, FramePerSecond = motion.FramePerSecond, FrameCount = motion.FrameCount, Unk98 = motion.Unk98, Unk9c = motion.Unk9c, }; stream.Write(new byte[ReservedSize], 0, ReservedSize); BinaryMapping.WriteObject(stream, new Header { }); BinaryMapping.WriteObject(stream, new InterpolatedMotionInternal { }); header.StaticPoseCount = motion.StaticPose.Count; header.StaticPoseOffset = (int)(stream.Position - ReservedSize); foreach (var item in motion.StaticPose) { BinaryMapping.WriteObject(stream, item); } header.ModelBoneAnimationCount = motion.ModelBoneAnimation.Count; header.ModelBoneAnimationOffset = (int)(stream.Position - ReservedSize); foreach (var item in motion.ModelBoneAnimation.Select(Map)) { BinaryMapping.WriteObject(stream, item); } header.IKHelperAnimationCount = motion.IKHelperAnimation.Count; header.IKHelperAnimationOffset = (int)(stream.Position - ReservedSize); foreach (var item in motion.IKHelperAnimation.Select(Map)) { BinaryMapping.WriteObject(stream, item); } header.TimelineOffset = (int)(stream.Position - ReservedSize); foreach (var item in rawTimeline) { BinaryMapping.WriteObject(stream, item); } stream.AlignPosition(4); header.KeyFrameCount = keyFramePool.Values.Count; header.KeyFrameOffset = (int)(stream.Position - ReservedSize); foreach (var item in keyFramePool.Values) { writer.Write(item); } header.TransformationValueOffset = (int)(stream.Position - ReservedSize); foreach (var item in valuePool.Values) { writer.Write(item); } header.TangentOffset = (int)(stream.Position - ReservedSize); foreach (var item in tangentPool.Values) { writer.Write(item); } header.IKChainCount = motion.IKChains.Count; header.IKChainOffset = (int)(stream.Position - ReservedSize); foreach (var item in motion.IKChains) { BinaryMapping.WriteObject(stream, item); } header.Unk48 = (int)(stream.Position - ReservedSize); stream.AlignPosition(0x10); header.Table8Offset = (int)(stream.Position - ReservedSize); foreach (var item in motion.Table8) { BinaryMapping.WriteObject(stream, item); } stream.AlignPosition(0x10); header.Table7Count = motion.Table7.Count; header.Table7Offset = (int)(stream.Position - ReservedSize); foreach (var item in motion.Table7) { BinaryMapping.WriteObject(stream, item); } header.Table6Count = motion.Table6.Count; header.Table6Offset = (int)(stream.Position - ReservedSize); foreach (var item in motion.Table6) { BinaryMapping.WriteObject(stream, item); } stream.AlignPosition(0x10); header.TotalBoneCount = (short)(motion.BoneCount + motion.IKHelpers.Count); header.IKHelperOffset = (int)(stream.Position - ReservedSize); foreach (var item in motion.IKHelpers) { BinaryMapping.WriteObject(stream, item); } header.JointIndexOffset = (int)(stream.Position - ReservedSize); foreach (var item in motion.Joints) { BinaryMapping.WriteObject(stream, item); } stream.AlignPosition(0x10); header.FooterOffset = (int)(stream.Position - ReservedSize); BinaryMapping.WriteObject(stream, motion.Footer); header.UnknownTable1Offset = (int)(stream.Position - ReservedSize); header.UnknownTable1Count = 0; stream.AlignPosition(0x10); stream.SetLength(stream.Position); stream.SetPosition(ReservedSize); BinaryMapping.WriteObject(stream, new Header { Version = 0, Unk04 = unkFlag ? 1 : 0, ByteCount = (int)(stream.Length - ReservedSize), Unk0c = 0, }); BinaryMapping.WriteObject(stream, header); }
public void Write(Stream stream) { var collisionList = new List <Collision>(); var collisionMeshList = new List <RawCollisionMesh>(); var collisionMeshGroupList = new List <RawNode>(); foreach (var node in Nodes) { var start = node.Meshes.Count > 0 ? collisionMeshList.Count : 0; collisionMeshGroupList.Add(new RawNode { Child1 = node.Child1, Child2 = node.Child2, Child3 = node.Child3, Child4 = node.Child4, Child5 = node.Child5, Child6 = node.Child6, Child7 = node.Child7, Child8 = node.Child8, BoundingBox = node.BoundingBox, CollisionMeshStart = (ushort)start, CollisionMeshEnd = (ushort)(start + node.Meshes.Count) }); foreach (var mesh in node.Meshes) { collisionMeshList.Add(new RawCollisionMesh { BoundingBox = mesh.BoundingBox, CollisionStart = (ushort)collisionList.Count, CollisionEnd = (ushort)(collisionList.Count + mesh.Collisions.Count), Visibility = mesh.Visibility, Group = mesh.Group }); collisionList.AddRange(mesh.Collisions); } } var bbCache = new WriteCache <BoundingBoxInt16, string>(x => x.ToString()); bbCache.AddConstant(BoundingBoxInt16.Invalid, -1); foreach (var item in collisionList) { bbCache.Add(item.BoundingBox); } var surfaceCache = new WriteCache <Attributes, int>(x => x.Flags); foreach (var item in collisionList) { surfaceCache.Add(item.Attributes); } var planeCache = new WriteCache <Plane, string>(x => x.ToString()); foreach (var item in collisionList) { planeCache.Add(item.Plane); } var entries = new List <Entry>(8); AddEntry(entries, HeaderSize, 1); AddEntry(entries, Nodes.Count * NodeSize, 0x10); AddEntry(entries, collisionMeshList.Count * MeshSize, 0x10); AddEntry(entries, collisionList.Count * PolygonSize, 4); AddEntry(entries, VertexList.Count * Col4Size, 0x10); AddEntry(entries, planeCache.Count * Col5Size, 0x10); AddEntry(entries, bbCache.Count * BoundingBoxSize, 0x10); AddEntry(entries, surfaceCache.Count * AttributesSize, 4); stream.Position = 0; BinaryMapping.WriteObject(stream, new Header { MagicCode = MagicCode, Version = 1, Depth = Depth, Type = Type, Entries = entries.ToArray() }); WriteCoctEntry(stream, collisionMeshGroupList); WriteCoctEntry(stream, collisionMeshList); WriteCoctEntry(stream, collisionList .Select(x => new RawCollision { Ground = x.Ground, FloorLevel = x.FloorLevel, Vertex1 = x.Vertex1, Vertex2 = x.Vertex2, Vertex3 = x.Vertex3, Vertex4 = x.Vertex4, PlaneIndex = planeCache[x.Plane], BoundingBoxIndex = bbCache[x.BoundingBox], AttributeIndex = surfaceCache[x.Attributes], })); stream.AlignPosition(0x10); WriteValueEntry(stream, VertexList, WriteVector4); WriteValueEntry(stream, planeCache, WritePlane); WriteValueEntry(stream, bbCache, WriteBoundingBoxInt16); WriteCoctEntry(stream, surfaceCache); }
public void Write(Stream stream) { stream.Position = HeaderLength; stream.Write(OffsetData); stream.AlignPosition(0x10); var texInfo1Offset = (int)stream.Position; foreach (var textureInfo in _textureInfo) { BinaryMapping.WriteObject(stream, new _TextureInfo { Data00 = 0x10000006, Data04 = 0x00000000, Data08 = 0x13000000, Data0c = 0x50000006, Data10 = 0x00000004, Data14 = 0x10000000, Data18 = 0x0000000e, Data1c = 0x00000000, Data20 = 0x00000000, Data24 = textureInfo.Data24, Data28 = textureInfo.Data28, Data2c = 0x00000000, Data30 = 0x00000000, Data34 = 0x00000000, Data38 = 0x00000051, Data3c = 0x00000000, Data40 = textureInfo.Data40, Data44 = textureInfo.Data44, Data48 = 0x00000052, Data4c = 0x00000000, Data50 = 0x00000000, Data54 = 0x00000000, Data58 = 0x00000053, Data5c = 0x00000000, Data60 = textureInfo.Data60, Data64 = 0x08000000, Data68 = 0x00000000, Data6c = 0x00000000, Data70 = textureInfo.Data70, PictureOffset = textureInfo.PictureOffset, Data78 = 0x00000000, Data7c = textureInfo.Data7c, Data80 = textureInfo.Data80, Data84 = 0x00000000, Data88 = 0x13000000, Data8c = 0x00000000, }); } var texInfo2Offset = (int)stream.Position; foreach (var textureInfo in _gsInfo) { BinaryMapping.WriteObject(stream, new _GsInfo { Data00 = 0x0000000010000008, Data08 = 0x5000000813000000, Data10 = 0x1000000000008007, Data18 = 0x000000000000000e, Data20 = 0x0000000000000000, Data28 = 0x000000000000003f, Data30 = textureInfo.Data30, Data38 = 0x0000000000000034, Data40 = textureInfo.Data40, Data48 = 0x0000000000000036, Data50 = textureInfo.Data50, Data58 = 0x0000000000000016, Data60 = textureInfo.Data60, Data68 = 0x0000000000000014, GsTex0 = textureInfo.GsTex0, Data78 = textureInfo.Data78, Data80 = textureInfo.Data80, Data88 = 0x0000000000000008, Data90 = 0x0000000060000000, Data98 = 0x0000000013000000, }); } stream.AlignPosition(0x80); var pictureOffset = (int)stream.Position; stream.Write(PictureData); var paletteOffset = (int)stream.Position; stream.Write(PaletteData); stream.Write(FooterData); var writer = new BinaryWriter(stream.SetPosition(0)); writer.Write(MagicCode); writer.Write(PaletteData.Length / 4); writer.Write(_textureInfo.Count - 1); writer.Write(_gsInfo.Count); writer.Write(HeaderLength); writer.Write(texInfo1Offset); writer.Write(texInfo2Offset); writer.Write(pictureOffset); writer.Write(paletteOffset); }