private void Save(string filePath) { FilePath = filePath; using (BinaryWriterExt w = new BinaryWriterExt(new FileStream(filePath, FileMode.Create))) { w.BigEndian = true; w.Write(0); w.Write(0); w.Write(Sounds.Count); w.Write(Unknown); int headerSize = 0; foreach (var s in Sounds) { headerSize += 8 + s.Channels.Count * 0x40; } var projData = headerSize + 0x20; foreach (var s in Sounds) { w.Write(s.Channels.Count); w.Write(s.Frequency); foreach (var channel in s.Channels) { var sa = (projData - (headerSize + 0x20) + 1) * 2; projData += channel.Data.Length; if (projData % 0x8 != 0) { projData += 0x08 - projData % 0x08; } var en = sa + channel.NibbleCount; w.Write(channel.LoopFlag); w.Write(channel.Format); w.Write(sa + channel.LoopStart); w.Write(en); w.Write(sa); foreach (var v in channel.COEF) { w.Write(v); } w.Write(channel.Gain); w.Write(channel.InitialPredictorScale); w.Write(channel.InitialSampleHistory1); w.Write(channel.InitialSampleHistory2); w.Write(channel.LoopPredictorScale); w.Write(channel.LoopSampleHistory1); w.Write(channel.LoopSampleHistory2); w.Write((short)0); } } var start = w.BaseStream.Position; foreach (var s in Sounds) { foreach (var c in s.Channels) { w.Write(c.Data); if (w.BaseStream.Position % 0x08 != 0) { w.Write(new byte[0x08 - w.BaseStream.Position % 0x08]); } } } // align 0x20 if (w.BaseStream.Position % 0x20 != 0) { w.Write(new byte[0x20 - w.BaseStream.Position % 0x20]); } var DataSize = w.BaseStream.Position - start; if (DataSize % 0x20 != 0) { w.Write(new byte[0x20 - DataSize % 0x20]); w.Write(0); w.Write(0); DataSize += 0x20 - DataSize % 0x20; } w.Seek(0); w.Write(headerSize); w.Write((int)DataSize); } }
/// <summary> /// /// </summary> /// <param name="code"></param> /// <param name="r"></param> /// <returns></returns> public void Encode(byte code, object[] p, BinaryWriterExt w) { if (Parameters.Length != p.Length && (code & 0xF0) != 0xC0 && (code & 0xF0) != 0xD0 && (code & 0xF8) != 0x80 && (code & 0xF8) != 0x88 && (code & 0xF8) != 0x90 && (code & 0xF8) != 0x98) { throw new ArgumentOutOfRangeException($"Op Code 0x{code.ToString("X")} expected {Parameters.Length} argument(s) and recieved {p.Length}"); } var codepos = w.BaseStream.Position; w.Write((byte)0); for (int i = 0; i < Parameters.Length; i++) { var k = Parameters[i]; switch (k) { case 'e': { var param = (short)p[i]; if (param >= 0x80) { w.Write((byte)(((param >> 8) & 0x7F) | 0x80)); w.Write((byte)(param & 0xFF)); } else { w.Write((byte)param); } } break; case 'b': w.Write((byte)p[i]); break; case 'f': w.Write((float)p[i]); break; case 's': w.Write((short)p[i]); break; case 'c': { byte param_count = 0; for (int j = 0; j < p.Length; j++) { param_count |= (byte)(1 << j); } code = ((byte)((code & 0xF0) | param_count)); for (int j = 1; j < p.Length; j++) { w.Write((byte)p[j]); } } break; case 'p': case 'v': { byte param_count = 0; for (int j = 0; j < p.Length; j++) { param_count |= (byte)(1 << j); } code = ((byte)((code & 0xF8) | param_count)); for (int j = 0; j < p.Length; j++) { w.Write((float)p[j]); } } break; case 'r': { var beh = 0; if ((bool)p[0]) { beh |= 0x10; } if ((bool)p[1]) { beh |= 0x20; } byte param_count = 0; for (int j = 0; j < p.Length - 3; j++) { param_count |= (byte)(1 << j); } w.Write((byte)(beh | param_count)); w.Write((byte)p[2]); for (int j = 3; j < p.Length; j++) { w.Write((byte)p[j]); } } break; case 'm': { w.Write((byte)0x09); w.Write((byte)p[0]); w.Write((byte)p[0]); } break; } } var temp = w.BaseStream.Position; w.Seek((uint)codepos); w.Write(code); w.Seek((uint)temp); }
/// <summary> /// Saves to File /// </summary> /// <param name="filename"></param> public void Save(string filename) { using (BinaryWriterExt w = new BinaryWriterExt(new FileStream(filename, FileMode.Create))) { w.BigEndian = true; if (Joints.Count == 0) { return; } var animStart = (uint)w.BaseStream.Position; w.Write(Joints.Count); w.Write(0x10); w.Write(PlaySpeed); w.Write(EndTime); // padding var headerStart = w.BaseStream.Position; w.Write(new byte[Joints.Count * 0x20]); for (int j = 0; j < Joints.Count; j++) { var joint = Joints[j]; var temp = (uint)w.BaseStream.Position; w.Seek((uint)(headerStart + j * 0x20)); w.Write(joint.Flag1); w.Write(joint.Flag2); w.Write((short)joint.TrackFlag); w.Write(joint.BoneID); w.Write((short)joint.Keys.Count); w.Write(joint.MaxTime); w.Write(joint.Unknown); w.Seek(temp); WriteAt(w, (int)(headerStart + j * 0x20 + 0x10), (int)(w.BaseStream.Position - animStart)); foreach (var k in joint.Keys) { w.Write(k.Time); } if (w.BaseStream.Position % 0x10 != 0) { w.Write(new byte[0x10 - w.BaseStream.Position % 0x10]); } if (joint.Flag1 == 0x02) { WriteAt(w, (int)(headerStart + j * 0x20 + 0x14), (int)(w.BaseStream.Position - animStart)); foreach (var k in joint.Keys) { w.Write((BitConverter.ToInt16(BitConverter.GetBytes(k.X), 2))); w.Write((BitConverter.ToInt16(BitConverter.GetBytes(k.Y), 2))); w.Write((BitConverter.ToInt16(BitConverter.GetBytes(k.Z), 2))); w.Write((BitConverter.ToInt16(BitConverter.GetBytes(k.W), 2))); } if (w.BaseStream.Position % 0x10 != 0) { w.Write(new byte[0x10 - w.BaseStream.Position % 0x10]); } } } } }