Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }