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(); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }