private static DmaChain ReadDmaChain(Stream stream, DmaChainHeader dmaChainHeader) { var dmaVifs = new List <DmaVif>(); var count1a = stream.SetPosition(dmaChainHeader.Count1aOffset).ReadInt32(); var alv1 = For(count1a, () => stream.ReadInt32()).ToList(); var offsetDmaPackets = new List <int>(); var alaxi = new List <int[]>(); var alaxref = new List <int>(); offsetDmaPackets.Add(dmaChainHeader.DmaOffset); var offsetDmaBase = dmaChainHeader.DmaOffset + 0x10; for (var i = 0; i < count1a; i++) { if (alv1[i] == -1) { offsetDmaPackets.Add(offsetDmaBase + 0x10); offsetDmaBase += 0x20; alaxi.Add(alaxref.ToArray()); alaxref.Clear(); } else { offsetDmaBase += 0x10; alaxref.Add(alv1[i]); } } alaxi.Add(alaxref.ToArray()); alaxref.Clear(); var dmaPackets = offsetDmaPackets .Select(offset => ReadTags(stream.SetPosition(offset)).ToArray()) .ToArray(); for (var i = 0; i < offsetDmaPackets.Count; i++) { var dmaTag = dmaPackets[i][0].DmaTag; var baseAddress = dmaTag.Qwc != 0 ? dmaPackets[i][1].Parameter : 0; stream.Position = dmaTag.Address & 0x7FFFFFFF; var vifPacket = stream.ReadBytes(dmaTag.Qwc * 0x10); dmaVifs.Add(new DmaVif(dmaChainHeader.TextureIndex, alaxi[i], vifPacket, baseAddress)); } return(new DmaChain { Unk00 = dmaChainHeader.Unk00, TextureIndex = dmaChainHeader.TextureIndex, Unk08 = dmaChainHeader.Unk08, DmaLength = dmaChainHeader.DmaLength, DmaVifs = dmaVifs, }); }
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); }