public static byte[] Save(TDX tdx) { byte[] buffer; using (MemoryStream ms = new MemoryStream()) using (BinaryWriter bw = new BinaryWriter(ms)) { bw.Write(new byte[] { 0, 2 }); bw.Write((short)tdx.MipMaps[0].Width); bw.Write((short)tdx.MipMaps[0].Height); bw.Write((short)tdx.MipMaps.Count); bw.Write((int)tdx.Flags); bw.Write((int)tdx.Format); for (int i = 0; i < tdx.MipMaps.Count; i++) { bw.Write(tdx.MipMaps[i].Data); } bw.Flush(); ms.Flush(); buffer = ms.ToArray(); } return(buffer); }
public static TDX Load(string path) { Logger.LogToFile(Logger.LogLevel.Info, "{0}", path); TDX tdx = new TDX(); using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(path))) { tdx = Load(ms, Path.GetFileNameWithoutExtension(path)); } return(tdx); }
public static TDX Load(Stream stream, string name = null) { TDX tdx = new TDX { Name = name }; using (BinaryReader br = new BinaryReader(stream)) { if (br.ReadByte() != 0x00 || br.ReadByte() != 0x02) { Logger.LogToFile(Logger.LogLevel.Error, "This isn't a valid TDX"); return(null); } tdx.Width = br.ReadUInt16(); tdx.Height = br.ReadUInt16(); int mipCount = br.ReadUInt16(); tdx.Flags = (TDXFlags)br.ReadUInt32(); tdx.Format = (D3DFormat)br.ReadUInt32(); if (tdx.Flags.HasFlag(TDXFlags.ExtraData)) { int extraDataLength = (int)br.ReadUInt32(); int extraDataType = br.ReadUInt16(); switch (extraDataType) { case 0: tdx.ExtraDataType = ExtraDataTypes.Font; tdx.ExtraData = new FontDefinition(br.ReadBytes(extraDataLength - 2)); break; case 1: tdx.ExtraDataType = ExtraDataTypes.Animation; tdx.ExtraData = new AnimationDefinition(br.ReadBytes(extraDataLength - 2)); break; case 3: tdx.ExtraDataType = ExtraDataTypes.VTMap; tdx.ExtraData = new VTMap(br.ReadBytes(extraDataLength - 2)); break; default: throw new NotImplementedException($"Unknown Extra Data flag: {extraDataType}"); } } for (int i = 0; i < mipCount; i++) { MipMap mip = new MipMap() { Width = tdx.Width >> i, Height = tdx.Height >> i }; switch (tdx.Format) { case D3DFormat.PVRTC4: mip.Data = br.ReadBytes(mip.Width * mip.Height / 2); break; case D3DFormat.R4G4B4A4: case D3DFormat.R5G5B6: case D3DFormat.R5G6B5: mip.Data = br.ReadBytes(mip.Width * mip.Height * 2); break; case D3DFormat.A8B8G8R8: mip.Data = br.ReadBytes(mip.Width * mip.Height * 4); break; case D3DFormat.A8R8G8B8: mip.Data = br.ReadBytes(mip.Width * mip.Height * (tdx.Flags.HasFlag(TDXFlags.AlphaNbit) ? 4 : 3)); break; case D3DFormat.A8: mip.Data = br.ReadBytes(mip.Width * mip.Height); break; case D3DFormat.DXT1: mip.Data = br.ReadBytes((mip.Width + 3) / 4 * ((mip.Height + 3) / 4) * 8); break; case D3DFormat.ATI2: case D3DFormat.DXT5: mip.Data = br.ReadBytes((mip.Width + 3) / 4 * ((mip.Height + 3) / 4) * 16); break; default: Logger.LogToFile(Logger.LogLevel.Error, "Unknown format: {0}", tdx.Format); return(null); } tdx.MipMaps.Add(mip); } } return(tdx); }
public static TDX LoadFromBitmap(Bitmap asset, string name, D3DFormat format) { TDX tdx = null; if (tdx == null) { tdx = new TDX(); Bitmap b = asset; SquishFlags flags = SquishFlags.kDxt1; tdx.Name = name; tdx.Format = format; switch (tdx.Format) { case D3DFormat.DXT1: flags = SquishFlags.kDxt1; break; case D3DFormat.DXT5: flags = SquishFlags.kDxt5; break; } List <Bitmap> mipBitmaps = GenerateMips(b, b.Width, b.Height); foreach (Bitmap mb in mipBitmaps) { MipMap mip = new MipMap() { Width = mb.Width, Height = mb.Height }; byte[] data = new byte[mb.Width * mb.Height * 4]; byte[] dest = new byte[Squish.Squish.GetStorageRequirements(mb.Width, mb.Height, flags | SquishFlags.kColourIterativeClusterFit | SquishFlags.kWeightColourByAlpha)]; int ii = 0; for (int y = 0; y < mb.Height; y++) { for (int x = 0; x < mb.Width; x++) { Color p = mb.GetPixel(x, y); data[ii + 0] = p.R; data[ii + 1] = p.G; data[ii + 2] = p.B; data[ii + 3] = p.A; ii += 4; } } if (format == D3DFormat.ATI2) { dest = BC5Unorm.Compress(data, (ushort)mb.Width, (ushort)mb.Height, GetMipSize(format, (ushort)mb.Width, (ushort)mb.Height)); } else { Squish.Squish.CompressImage(data, mb.Width, mb.Height, ref dest, flags | SquishFlags.kColourClusterFit); } mip.Data = dest; tdx.MipMaps.Add(mip); } } return(tdx); }