using System.IO; using System.Text; using PckStudio.Core.FileFormats; using OMI.Workers; using OMI; using System; using OpenTK; using PckStudio.Core.Skin; namespace PckStudio.ModelSupport.Internal.Format { internal class PSMFileWriter : IDataFormatWriter { PSMFile _PSM; public PSMFileWriter(PSMFile csmb) { _PSM = csmb; } public void WriteToFile(string filename) { using(var fs = File.OpenWrite(filename)) { WriteToStream(fs); } } public void WriteToStream(Stream stream) { using (var writer = new EndiannessAwareBinaryWriter(stream, Encoding.ASCII, leaveOpen: true, ByteOrder.LittleEndian)) { writer.WriteString(PSMFile.HEADER_MAGIC); writer.Write(_PSM.Version); writer.Write(_PSM.SkinANIM.ToValue()); writer.Write(_PSM.Parts.Count); foreach (SkinBOX part in _PSM.Parts) { WritePart(writer, part); } writer.Write(_PSM.Offsets.Count); foreach (SkinPartOffset offset in _PSM.Offsets) { writer.Write((byte)GetOffsetPart(offset.Type)); writer.Write(offset.Value); } } } private void WritePart(EndiannessAwareBinaryWriter writer, SkinBOX part) { writer.Write((byte)GetParentPart(part.Type)); writer.Write(part.Pos.X); writer.Write(part.Pos.Y); writer.Write(part.Pos.Z); writer.Write(part.Size.X); writer.Write(part.Size.Y); writer.Write(part.Size.Z); byte uvX = (byte)MathHelper.Clamp((int)part.UV.X, 0, 64); byte uvY = (byte)MathHelper.Clamp((int)part.UV.Y, 0, 64); byte mirrorAndUvX = (byte)(Convert.ToByte(part.Mirror) << 7 | uvX); byte hideWithArmorAndUvY = (byte)(Convert.ToByte(part.ArmorMaskFlags) << 7 | uvY); writer.Write(mirrorAndUvX); writer.Write(hideWithArmorAndUvY); writer.Write(part.Scale); } private static PSMParentType GetParentPart(string type) { switch (type) { case "HEAD": return PSMParentType.HEAD; case "BODY": return PSMParentType.BODY; case "ARM0": return PSMParentType.ARM0; case "ARM1": return PSMParentType.ARM1; case "LEG0": return PSMParentType.LEG0; case "LEG1": return PSMParentType.LEG1; default: throw new InvalidDataException(type); } } private static PSMOffsetType GetOffsetPart(string type) { switch (type) { case "HEAD": return PSMOffsetType.HEAD; case "BODY": return PSMOffsetType.BODY; case "ARM0": return PSMOffsetType.ARM0; case "ARM1": return PSMOffsetType.ARM1; case "LEG0": return PSMOffsetType.LEG0; case "LEG1": return PSMOffsetType.LEG1; case "TOOL0": return PSMOffsetType.TOOL0; case "TOOL1": return PSMOffsetType.TOOL1; case "HELMET": return PSMOffsetType.HELMET; case "SHOULDER0": return PSMOffsetType.SHOULDER0; case "SHOULDER1": return PSMOffsetType.SHOULDER1; case "CHEST": return PSMOffsetType.CHEST; case "WAIST": return PSMOffsetType.WAIST; case "PANTS0": return PSMOffsetType.PANTS0; case "PANTS1": return PSMOffsetType.PANTS1; case "BOOT0": return PSMOffsetType.BOOT0; case "BOOT1": return PSMOffsetType.BOOT1; default: throw new InvalidDataException(type); } } } }