Esempio n. 1
0
        public void load(string filename)
        {
            m_entries.Clear();
            FileStream     stream = new FileStream(filename, FileMode.Open);
            BEBinaryReader reader = new BEBinaryReader(stream, Encoding.UTF8);

            // Read data header
            uint file_size    = reader.ReadUInt32();
            uint table_offset = reader.ReadUInt32() + HEADER_SIZE;

            reader.ReadUInt32();
            uint num_entries = reader.ReadUInt32();

            reader.ReadUInt32();
            reader.ReadUInt32();
            reader.ReadUInt32();
            reader.ReadUInt32();

            // Read entries
            for (uint i = 0; i < num_entries; ++i)
            {
                // Read table entry
                stream.Position = table_offset + i * ENTRY_SIZE;
                uint data_offset   = reader.ReadUInt32() + HEADER_SIZE;
                uint string_offset = reader.ReadUInt32() + table_offset + num_entries * ENTRY_SIZE;

                // Read data string
                StringBuilder builder = new StringBuilder();
                stream.Position = string_offset;
                char c;
                while ((c = reader.ReadChar()) != '\0')
                {
                    builder.Append(c);
                }

                // Read data entry
                stream.Position = data_offset;
                T data = new T();
                data.load(reader);

                m_entries.Add(builder.ToString(), data);
            }

            reader.Close();
            stream.Close();
        }
Esempio n. 2
0
        public static ConversionStatus Convert(
            Stream input,
            Stream output)
        {
            using var reader = new BEBinaryReader(input);

            var header = new WoffHeader
            {
                Signature         = reader.ReadUInt32(),
                Flavor            = reader.ReadUInt32(),
                Length            = reader.ReadUInt32(),
                TableCount        = reader.ReadUInt16(),
                Reserved          = reader.ReadUInt16(),
                TotalSfntSize     = reader.ReadUInt32(),
                MajorVersion      = reader.ReadUInt16(),
                MinorVersion      = reader.ReadUInt16(),
                MetaOffset        = reader.ReadUInt32(),
                MetaLength        = reader.ReadUInt32(),
                MetaOrignalLength = reader.ReadUInt32(),
                PrivOffset        = reader.ReadUInt32(),
                PrivLength        = reader.ReadUInt32()
            };

            if (header.Signature is not 0x774F4646)
            {
                if (header.Signature is 0x774F4632)
                {
                    return(ConversionStatus.UnsupportedWOFF2);
                }
                else
                {
                    return(ConversionStatus.UnrecognisedFile);
                }
            }


            UInt32 offset = 12;

            // Read Table Headers
            List <TableDirectory> entries = new List <TableDirectory>();

            for (var i = 0; i < header.TableCount; i++)
            {
                var entry = new TableDirectory
                {
                    Tag              = reader.ReadUInt32(),
                    Offset           = reader.ReadUInt32(),
                    CompressedLength = reader.ReadUInt32(),
                    OriginalLength   = reader.ReadUInt32(),
                    OriginalChecksum = reader.ReadUInt32()
                };

                if (Name(entry.Tag) == "DSIG") // Conversion invalidates
                {
                    continue;
                }

                entries.Add(entry);
                offset += (4 * 4);
            }

            // Amend table count after removing DSIG
            header.TableCount = (ushort)entries.Count;

            // Calculate header values
            UInt16 entrySelector = 0;

            while (Math.Pow(2, entrySelector) <= header.TableCount)
            {
                entrySelector++;
            }
            entrySelector--;

            UInt16 searchRange = (UInt16)(Math.Pow(2, entrySelector) * 16);
            UInt16 rangeShift  = (UInt16)(header.TableCount * 16 - searchRange);

            // Create writer
            using var writer = new BEBinaryWriter(output);

            // Write Font Header
            writer.Write(header.Flavor);
            writer.Write(header.TableCount);
            writer.Write(searchRange);
            writer.Write(entrySelector);
            writer.Write(rangeShift);

            // Write Table Headers
            foreach (var entry in entries)
            {
                writer.Write(entry.Tag);
                writer.Write(entry.OriginalChecksum);
                writer.Write(offset);
                writer.Write(entry.OriginalLength);
                entry.OutputOffset = offset;

                offset += entry.OriginalLength;
                if ((offset % 4) != 0)
                {
                    offset += 4 - (offset % 4);
                }
            }

            // Write Table contents
            foreach (var entry in entries)
            {
                input.Seek(entry.Offset, SeekOrigin.Begin);
                byte[] compressed = reader.ReadBytes((int)entry.CompressedLength);
                byte[] uncompressed;
                if (entry.CompressedLength != entry.OriginalLength)
                {
                    // Decompress table
                    using var comp = new MemoryStream(compressed.AsSpan().Slice(2).ToArray()); // Ignore the ZLib header (2 bytes long)
                    using var outs = new MemoryStream();
                    using var def  = new DeflateStream(comp, CompressionMode.Decompress);
                    def.CopyTo(outs);
                    uncompressed = outs.ToArray();
                }
                else
                {
                    uncompressed = compressed;
                }

                if (uncompressed.Length != entry.OriginalLength)
                {
                    return(ConversionStatus.TableLengthMismatch);
                }

                if (entry.ToString() == "name")
                {
                    if (TryFixNameTable(ref uncompressed) is byte[] ammended)
                    {
                        uncompressed = ammended;
                    }
                }

                output.Seek(entry.OutputOffset, SeekOrigin.Begin);
                writer.Write(uncompressed);
                offset = (uint)output.Position;
                if (offset % 4 != 0)
                {
                    uint padding = 4 - (offset % 4);
                    writer.Write(new byte[padding]);
                }
            }

            writer.Flush();
            output.Flush();

            return(ConversionStatus.OK);
        }
Esempio n. 3
0
        public static EXP Load(string path)
        {
            FileInfo fi = new FileInfo(path);

            Logger.LogToFile(Logger.LogLevel.Info, "{0}", path);
            EXP exp = new EXP()
            {
                name     = Path.GetFileNameWithoutExtension(path),
                location = Path.GetDirectoryName(path) + "\\"
            };

            using (BEBinaryReader br = new BEBinaryReader(fi.OpenRead()))
            {
                while (br.BaseStream.Position < br.BaseStream.Length)
                {
                    string section = br.ReadString(4);
                    int    length  = 0;

                    switch (section)
                    {
                    case "FORM":
                        length = (int)br.ReadUInt32();
                        break;

                    case "TERR":
                    case "XOBF":
                        break;

                    case "TITL":
                        length = (int)br.ReadUInt32();
                        if (length > 0)
                        {
                            throw new NotImplementedException(string.Format("TITL section has a length ({0}), don't know what to do!", length));
                        }
                        break;

                    case "TEXT":
                        length = (int)br.ReadUInt32();
                        if (length > 0)
                        {
                            throw new NotImplementedException(string.Format("TEXT section has a length ({0}), don't know what to do!", length));
                        }
                        break;

                    case "HEAD":
                        length = (int)br.ReadUInt32();
                        Logger.LogToFile(Logger.LogLevel.Debug, "U: {0}", br.ReadUInt16());
                        Logger.LogToFile(Logger.LogLevel.Debug, "U: {0}", br.ReadUInt32());
                        exp.entryCount = br.ReadUInt16();
                        Logger.LogToFile(Logger.LogLevel.Debug, "U: {0}", br.ReadUInt32());
                        Logger.LogToFile(Logger.LogLevel.Debug, "U: {0}", br.ReadUInt16());
                        Logger.LogToFile(Logger.LogLevel.Debug, "U: {0}", br.ReadUInt16());
                        Logger.LogToFile(Logger.LogLevel.Debug, "U: {0}", br.ReadUInt16());
                        Logger.LogToFile(Logger.LogLevel.Debug, "U: {0}", br.ReadUInt32());
                        Logger.LogToFile(Logger.LogLevel.Debug, "U: {0}", br.ReadUInt32());
                        break;

                    case "BIN ":
                        length = (int)br.ReadUInt32();
                        exp.contents.Add(new EXPEntry {
                            Size = length, Offset = (int)br.BaseStream.Position, EntryType = EXPEntryType.Binary
                        });
                        br.ReadBytes(length);
                        break;

                    case "ANM ":
                        length = (int)br.ReadUInt32();
                        exp.contents.Add(new EXPEntry {
                            Size = length, Offset = (int)br.BaseStream.Position, EntryType = EXPEntryType.Animation
                        });
                        br.ReadBytes(length);
                        break;

                    case "PLTX":
                        length = (int)br.ReadUInt32();
                        if (length > 0)
                        {
                            throw new NotImplementedException(string.Format("PLTX section has a length ({0}), don't know what to do!", length));
                        }
                        break;

                    default:
                        throw new NotImplementedException(string.Format("Unexpected section \"{0}\" at {1,0:X0}", section, br.BaseStream.Position - 4));
                    }
                }
            }

            return(exp);
        }
Esempio n. 4
0
        public static ACT Load(string path)
        {
            FileInfo fi = new FileInfo(path);

            Logger.LogToFile(Logger.LogLevel.Info, "{0}", path);
            ACT act = new ACT();

            using (BEBinaryReader br = new BEBinaryReader(fi.OpenRead(), Encoding.Default))
            {
                if (br.ReadUInt32() != 0x12 ||
                    br.ReadUInt32() != 0x8 ||
                    br.ReadUInt32() != 0x1 ||
                    br.ReadUInt32() != 0x2)
                {
                    Logger.LogToFile(Logger.LogLevel.Error, "{0} isn't a valid ACT file", path);
                    return(null);
                }

                ACTNode a;

                while (br.BaseStream.Position < br.BaseStream.Length)
                {
                    Section tag = (Section)br.ReadUInt32();
                    int     _   = (int)br.ReadUInt32();

                    a = new ACTNode(tag);

                    switch (tag)
                    {
                    case Section.Name:      // 00 00 00 23
                        a.ActorType   = (ActorType)br.ReadByte();
                        a.RenderStyle = (RenderStyle)br.ReadByte();
                        a.Identifier  = br.ReadString();
                        if (a.Identifier.Length == 0)
                        {
                            a.Identifier = "NO_IDENTIFIER";
                        }
                        break;

                    case Section.Model:
                        a.Model = br.ReadString();
                        break;

                    case Section.Section37:     // 00 00 00 25
                        break;

                    case Section.Material:
                        a.Material = br.ReadString();
                        break;

                    case Section.SubLevelBegin:     // 00 00 00 29
                        break;

                    case Section.SubLevelEnd:
                        break;

                    case Section.Matrix:     // 00 00 00 2B
                        a.Transform = new Matrix3D(br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                        break;

                    case Section.BoundingBox:     // 00 00 00 32
                        a.Bounds = new MeshExtents(new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()), new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()));
                        break;

                    case Section.EOF:
                        break;

                    default:
                        Console.WriteLine("Unknown ACT tag: {0} ({1} of {2})", tag, br.BaseStream.Position, br.BaseStream.Length);
                        return(null);
                    }

                    act.Sections.Add(a);
                }
            }

            return(act);
        }
Esempio n. 5
0
        public static DAT Load(string path)
        {
            FileInfo fi = new FileInfo(path);

            Logger.LogToFile(Logger.LogLevel.Info, "{0}", path);
            DAT dat = new DAT();

            DatMesh D = new DatMesh();
            int     count;

            using (BEBinaryReader br = new BEBinaryReader(fi.OpenRead(), Encoding.Default))
            {
                if (br.ReadUInt32() != 0x12 ||
                    br.ReadUInt32() != 0x8 ||
                    br.ReadUInt32() != 0xFACE ||
                    br.ReadUInt32() != 0x2)
                {
                    Logger.LogToFile(Logger.LogLevel.Error, "{0} isn't a valid DAT file", path);
                    return(null);
                }

                while (br.BaseStream.Position < br.BaseStream.Length)
                {
                    int tag    = (int)br.ReadUInt32();
                    int length = (int)br.ReadUInt32();

                    switch (tag)
                    {
                    case 54:     // 00 00 00 36
                        D = new DatMesh()
                        {
                            UnknownAttribute = br.ReadUInt16(),       // I think this is actually two byte values
                            Name             = br.ReadString()
                        };
                        break;

                    case 23:     // 00 00 00 17 : vertex data
                        count = (int)br.ReadUInt32();

                        for (int i = 0; i < count; i++)
                        {
                            D.Mesh.AddListVertex(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                        }
                        break;

                    case 24:     // 00 00 00 18 : UV co-ordinates
                        count = (int)br.ReadUInt32();

                        for (int i = 0; i < count; i++)
                        {
                            D.Mesh.AddListUV(br.ReadSingle(), br.ReadSingle());
                        }
                        break;

                    case 53:        // 00 00 00 35 : faces
                        count = (int)br.ReadUInt32();

                        for (int i = 0; i < count; i++)
                        {
                            int faceID = D.Mesh.AddFace(br.ReadUInt16(), br.ReadUInt16(), br.ReadUInt16());

                            D.Mesh.Faces[faceID].SmoothingGroup = br.ReadUInt16();

                            br.ReadByte();     // number of edges, 0 and 3 = tri.  4 = quad.
                        }
                        break;

                    case 22:     // 00 00 00 16 : material list
                        D.Mesh.Materials.AddRange(br.ReadStrings((int)br.ReadUInt32()));
                        break;

                    case 26:             // 00 00 00 1A : face textures
                        count = (int)br.ReadUInt32();
                        br.ReadBytes(4); // f**k knows what this is
                        for (int i = 0; i < count; i++)
                        {
                            D.Mesh.SetMaterialForFace(i, br.ReadUInt16() - 1);
                        }
                        break;

                    case 0:
                        // EndOfFile
                        D.Mesh.ProcessMesh();
                        dat.DatMeshes.Add(D);
                        break;

                    default:
                        Logger.LogToFile(Logger.LogLevel.Error, "Unknown DAT tag: {0} ({1:x2})", tag, br.BaseStream.Position);
                        return(null);
                    }
                }
            }

            return(dat);
        }
Esempio n. 6
0
        public static MAT Load(string path)
        {
            FileInfo fi = new FileInfo(path);

            Logger.LogToFile(Logger.LogLevel.Info, "{0}", path);
            MAT mat = new MAT();

            MATMaterial M      = new MATMaterial();
            bool        bDebug = false;

            using (BEBinaryReader br = new BEBinaryReader(fi.OpenRead(), Encoding.Default))
            {
                br.ReadBytes(16); // Header

                while (br.BaseStream.Position < br.BaseStream.Length)
                {
                    int tag    = (int)br.ReadUInt32();
                    int length = (int)br.ReadUInt32();

                    switch (tag)
                    {
                    case 0x4:
                        // C1 mat file
                        M = new MATMaterial();

                        M.DiffuseColour[0]    = br.ReadByte();  // R
                        M.DiffuseColour[1]    = br.ReadByte();  // G
                        M.DiffuseColour[2]    = br.ReadByte();  // B
                        M.DiffuseColour[3]    = br.ReadByte();  // A
                        M.AmbientLighting     = br.ReadSingle();
                        M.DirectionalLighting = br.ReadSingle();
                        M.SpecularLighting    = br.ReadSingle();
                        M.SpecularPower       = br.ReadSingle();
                        M.SetFlags((int)br.ReadUInt16());     // Flags
                        if (M.GetFlag(MATMaterial.Settings.UnknownSetting) || M.GetFlag(MATMaterial.Settings.IFromV) || M.GetFlag(MATMaterial.Settings.UFromI) || M.GetFlag(MATMaterial.Settings.VFromI))
                        {
                            bDebug = true;
                        }
                        M.UVMatrix = new Matrix2D(br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                        byte x1 = br.ReadByte();     // ??
                        byte x2 = br.ReadByte();     // ??
                        M.Name = br.ReadString();

                        if (bDebug)
                        {
                            Console.WriteLine(path + " :: " + M.Name); bDebug = false;
                        }
                        break;

                    case 0x3c:
                        M = new MATMaterial();

                        M.DiffuseColour[0]    = br.ReadByte();  // R
                        M.DiffuseColour[1]    = br.ReadByte();  // G
                        M.DiffuseColour[2]    = br.ReadByte();  // B
                        M.DiffuseColour[3]    = br.ReadByte();  // A
                        M.AmbientLighting     = br.ReadSingle();
                        M.DirectionalLighting = br.ReadSingle();
                        M.SpecularLighting    = br.ReadSingle();
                        M.SpecularPower       = br.ReadSingle();
                        M.SetFlags((int)br.ReadUInt32());     // Flags
                        M.UVMatrix = new Matrix2D(br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                        if (br.ReadUInt32() != 169803776)
                        {
                            Console.WriteLine("Weird Beard! (" + path + ")");
                        }
                        br.ReadBytes(13);     // 13 bytes of nothing
                        M.Name = br.ReadString();
                        break;

                    case 0x1c:
                        M.Texture = br.ReadString();
                        break;

                    case 0x1f:
                        string _ = br.ReadString();     // shadetable
                        break;

                    case 0x0:
                        mat.Materials.Add(M);
                        break;

                    default:
                        Logger.LogToFile(Logger.LogLevel.Error, "Unknown MAT tag: {0} ({1})", tag, br.BaseStream.Position.ToString("X"));
                        return(null);
                    }
                }
            }

            return(mat);
        }
Esempio n. 7
0
        public static XT2 Load(string path)
        {
            FileInfo fi = new FileInfo(path);

            Console.WriteLine("{0}", path);
            XT2 xt2 = new XT2()
            {
                Name = fi.Name.Replace(fi.Extension, "")
            };

            using (BEBinaryReader br = new BEBinaryReader(fi.OpenRead()))
            {
                Console.WriteLine("Always 0 : {0}", br.ReadUInt32());

                int magic = (int)br.ReadUInt32();

                br.ReadUInt32();    // datasize
                Console.WriteLine("Always 52 : {0}", br.ReadUInt32());
                Console.WriteLine("Always 0 : {0}", br.ReadUInt16());
                xt2.Width  = br.ReadUInt16();
                xt2.Height = br.ReadUInt16();
                Console.WriteLine("{0} {1}", br.ReadUInt16(), br.ReadUInt16());

                xt2.Header = new D3DBaseTexture(br);

                int W          = 0;
                int H          = 0;
                int TexelPitch = 0;
                int DataSize   = 0;
                int OutSize    = 0;
                int w          = xt2.Width;
                int h          = xt2.Height;

                switch (xt2.Header.DataFormat)
                {
                    //case D3DFormat.X360_A8R8G8B8:
                    //    W = w;
                    //    H = h;
                    //    TexelPitch = 4;
                    //    DataSize = w * h * 4;
                    //    break;

                    //case D3DFormat.X360_DXT1:
                    //    W = w / 4;
                    //    H = h / 4;
                    //    TexelPitch = 8;
                    //    DataSize = w * h / 2;
                    //    break;

                    //case D3DFormat.X360_DXT2:
                    //    W = w / 4;
                    //    H = h / 4;
                    //    TexelPitch = 16;
                    //    DataSize = W * H;
                    //    break;
                }

                if (H % 128 != 0)
                {
                    H += 128 - H % 128;
                }

                switch (xt2.Header.DataFormat)
                {
                    //case D3DFormat.X360_A8R8G8B8:
                    //    OutSize = W * H * TexelPitch;
                    //    break;

                    //case D3DFormat.X360_DXT1:
                    //    OutSize = W * H * TexelPitch;
                    //    break;

                    //case D3DFormat.X360_DXT2:
                    //    DataSize = w * H * 2;
                    //    OutSize = W * H * TexelPitch;
                    //    break;
                }

                byte[] data    = new byte[DataSize];
                byte[] outdata = new byte[OutSize];

                Array.Copy(br.ReadBytes(DataSize), data, DataSize);

                int step = xt2.Header.Endian == 1 ? 2 : 4;
                for (int i = 0; i < data.Length; i += step)
                {
                    for (int j = 0; j < step / 2; j++)
                    {
                        byte tmp = data[i + j];
                        data[i + j]            = data[i + step - j - 1];
                        data[i + step - j - 1] = tmp;
                    }
                }

                for (int y = 0; y < H; y++)
                {
                    for (int x = 0; x < W; x++)
                    {
                        int offset = Xbox360ConvertTextureAddress(x, y, W, TexelPitch);
                        if (offset * TexelPitch < data.Length)
                        {
                            Array.Copy(data, offset * TexelPitch, outdata, (x + y * W) * TexelPitch, TexelPitch);
                        }
                    }
                }

                MipMap mip = new MipMap
                {
                    Width  = xt2.Width,
                    Height = xt2.Height,
                    Data   = data
                };

                xt2.MipMaps.Add(mip);
            }

            return(xt2);
        }
Esempio n. 8
0
        public static PIX Load(string path)
        {
            Logger.LogToFile(Logger.LogLevel.Info, "{0}", path);
            FileInfo fi  = new FileInfo(path);
            PIX      pix = new PIX();

            using (BEBinaryReader br = new BEBinaryReader(fi.OpenRead(), Encoding.Default))
            {
                if (br.ReadUInt32() != 0x12 ||
                    br.ReadUInt32() != 0x08 ||
                    br.ReadUInt32() != 0x02 ||
                    br.ReadUInt32() != 0x02)
                {
                    Logger.LogToFile(Logger.LogLevel.Error, "{0} isn't a valid PIX file", path);
                    return(null);
                }

                Stack <PIXIE> pixies = new Stack <PIXIE>();

                while (br.BaseStream.Position < br.BaseStream.Length)
                {
                    if (br.BaseStream.Position + 8 > br.BaseStream.Length)
                    {
                        Logger.LogToFile(Logger.LogLevel.Error, $"{path} is malformed.  The last {br.BaseStream.Length - br.BaseStream.Position} bytes are redundant and should be removed");
                        break;
                    }

                    int tag = (int)br.ReadUInt32();
                    br.ReadUInt32();        // length

                    switch (tag)
                    {
                    case 0x03:      // 3
                        pixies.Push(new PIXIE()
                        {
                            Format     = (PIXIE.PixelmapFormat)br.ReadByte(),
                            RowSize    = br.ReadUInt16(),
                            Width      = br.ReadUInt16(),
                            Height     = br.ReadUInt16(),
                            HalfWidth  = br.ReadUInt16(),
                            HalfHeight = br.ReadUInt16(),
                            Name       = br.ReadString()
                        });
                        break;

                    case 0x21:      // 33
                        pixies.Peek().PixelCount = (int)br.ReadUInt32();
                        pixies.Peek().PixelSize  = (int)br.ReadUInt32();
                        pixies.Peek().SetData(br.ReadBytes(pixies.Peek().DataLength));
                        break;

                    case 0x22:      // 34
                    case 0x00:      // 0
                        pix.Pixies.Add(pixies.Pop());
                        break;

                    case 0x3d:
                        pixies.Push(new PIXIE
                        {
                            Format  = (PIXIE.PixelmapFormat)br.ReadByte(),
                            RowSize = br.ReadUInt16(),
                            Width   = br.ReadUInt16(),
                            Height  = br.ReadUInt16()
                        });
                        br.ReadBytes(6);
                        pixies.Peek().Name = br.ReadString();
                        break;

                    default:
                        Logger.LogToFile(Logger.LogLevel.Error, "Unknown PIX tag: {0} ({1:x2})", tag, br.BaseStream.Position);
                        return(null);
                    }
                }
            }

            return(pix);
        }