private void ParseHET() { Reader.Seek((long)HetTablePos64, SeekOrigin.Begin); if (Reader.Read <Media.FourCC>() != new Media.FourCC("HET\x1A")) { throw new Exception("WTF"); } if (Reader.ReadUInt32() != 1) { throw new Exception("WTF"); } HetDataSize = Reader.ReadUInt32(); HetTableSize = Reader.ReadUInt32(); HetMaxFileCount = Reader.ReadUInt16(); HetHashTableSize = Reader.ReadUInt16(); HetHashEntrySize = Reader.ReadUInt32(); HetTotalIndexSize = Reader.ReadUInt32(); HetIndexSizeExtra = Reader.ReadUInt32(); HetIndexSize = Reader.ReadUInt32(); HetBlockTableSize = Reader.ReadUInt32(); HetHashTableOffset = Reader.Position; }
private void ReadHeader70(Ibasa.IO.BinaryReader reader) { Width = reader.ReadUInt16(); Height = reader.ReadUInt16(); Flags = (TextureFlags)reader.ReadInt32(); Frames = reader.ReadUInt16(); StartFrame = reader.ReadUInt16(); reader.ReadBytes(4); //skip padding Reflectivity = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); reader.ReadBytes(4); //skip padding BumpmapScale = reader.ReadSingle(); ImageFormat = (ImageFormat)reader.ReadInt32(); MipmapCount = reader.ReadByte(); LowResImageFormat = (ImageFormat)reader.ReadInt32(); LowResImageWidth = reader.ReadByte(); LowResImageHeight = reader.ReadByte(); }
private void ReadHeader72(Ibasa.IO.BinaryReader reader) { if (VersionMinor >= 2) { Depth = reader.ReadUInt16(); Depth = Depth == 0 ? 1 : Depth; //map 0 to 1 } else { Depth = 1; reader.ReadBytes(1); //skip padding } }
private void ReadColorMap(Ibasa.IO.BinaryReader reader) { if (Header.ColorMapType == 0) { return; } ColorMap = new uint[256]; switch (Header.ColorMapDepth) { case 16: { for (int i = Header.ColourMapOrigin; i < Header.ColorMapLength; ++i) { uint color = reader.ReadUInt16(); uint r = (color >> 10) & 0x1F; uint g = (color >> 5) & 0x1F; uint b = (color) & 0x1F; //expand 8 bits r = (r << 3) | (r >> 2); g = (g << 3) | (g >> 2); b = (b << 3) | (b >> 2); ColorMap[i] = (r << 16) | (g << 8) | b; } } break; case 24: { for (int i = Header.ColourMapOrigin; i < Header.ColorMapLength; ++i) { uint b = reader.ReadByte(); uint g = reader.ReadByte(); uint r = reader.ReadByte(); ColorMap[i] = (r << 16) | (g << 8) | b; } } break; case 32: { for (int i = Header.ColourMapOrigin; i < Header.ColorMapLength; ++i) { ColorMap[i] = reader.ReadUInt32(); } } break; default: throw new InvalidDataException("Unrecognized color map depth."); } }
private void ReadDeveloper(Ibasa.IO.BinaryReader reader) { int tags = reader.ReadUInt16(); uint[] tol = new uint[tags * 3]; for (int i = 0; i < tags; ++i) { tol[i * 3 + 0] = reader.ReadUInt16(); tol[i * 3 + 1] = reader.ReadUInt32(); tol[i * 3 + 2] = reader.ReadUInt32(); } for (int i = 0; i < tags; ++i) { int tag = (int)tol[i * 3 + 0]; long offset = tol[i * 3 + 1]; int length = (int)tol[i * 3 + 2]; reader.BaseStream.Seek(offset, SeekOrigin.Begin); DeveloperArea.Add(new KeyValuePair <int, byte[]>(tag, reader.ReadBytes(length))); } }
private void ReadHeader(Ibasa.IO.BinaryReader reader) { Header.ImageId = new byte[reader.ReadByte()]; Header.ColorMapType = reader.ReadByte(); Header.ImageType = reader.ReadByte(); Header.ColourMapOrigin = reader.ReadUInt16(); Header.ColorMapLength = reader.ReadUInt16(); Header.ColorMapDepth = reader.ReadByte(); Header.XOrigin = reader.ReadUInt16(); Header.YOrigin = reader.ReadUInt16(); Header.Width = reader.ReadUInt16(); Header.Height = reader.ReadUInt16(); Header.PixelDepth = reader.ReadByte(); Header.ImageDescriptor = reader.ReadByte(); reader.Read(Header.ImageId, 0, Header.ImageId.Length); }
public Mpq(Stream stream) { Reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); long offset = 0; bool founda, foundb; { Ibasa.Media.FourCC mpqa = new Media.FourCC("MPQ\x1A"); Ibasa.Media.FourCC mpqb = new Media.FourCC("MPQ\x1B"); //find offset var fourcc = Reader.Read<Ibasa.Media.FourCC>(); founda = fourcc == mpqa; foundb = fourcc == mpqb; while (!founda && !foundb) { offset += 512; fourcc = Reader.Read<Ibasa.Media.FourCC>(); founda = fourcc == mpqa; foundb = fourcc == mpqb; } } if (foundb) { var userdatasize = Reader.ReadUInt32(); offset += Reader.ReadUInt32(); var userdataheader = Reader.ReadUInt32(); } Reader.Seek(offset, SeekOrigin.Begin); if (Reader.Read<Media.FourCC>() != new Media.FourCC("MPQ\x1A")) throw new Exception("WTF"); HeaderSize = Reader.ReadUInt32(); ArchiveSize = Reader.ReadUInt32(); FormatVersion = Reader.ReadUInt16(); BlockSize = Reader.ReadUInt16(); HashTablePos = Reader.ReadUInt32(); BlockTablePos = Reader.ReadUInt32(); HashTableSize = Reader.ReadUInt32(); BlockTableSize = Reader.ReadUInt32(); if (FormatVersion >= 2) { HiBlockTablePos64 = Reader.ReadUInt64(); HashTablePosHi = Reader.ReadUInt16(); BlockTablePosHi = Reader.ReadUInt16(); } if (FormatVersion >= 3) { ArchiveSize64 = Reader.ReadUInt64(); BetTablePos64 = Reader.ReadUInt64(); HetTablePos64 = Reader.ReadUInt64(); } if (FormatVersion >= 4) { hashtablesize64 = Reader.ReadUInt64(); blocktablesize64 = Reader.ReadUInt64(); hiblocktablesize64 = Reader.ReadUInt64(); hettablesize64 = Reader.ReadUInt64(); bettablesize64 = Reader.ReadUInt64(); dawchunksize = Reader.ReadUInt32(); md5_blocktable = Reader.ReadBytes(16); md5_hashtable = Reader.ReadBytes(16); md5_hiblocktable = Reader.ReadBytes(16); md5_bettable = Reader.ReadBytes(16); md5_hettable = Reader.ReadBytes(16); md5_mpqheader = Reader.ReadBytes(16); } if (HetTablePos64 != 0) { ParseHET(); } if (BetTablePos64 != 0) { ParseBET(); } }
public Mpq(Stream stream) { Reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); long offset = 0; bool founda, foundb; { Ibasa.Media.FourCC mpqa = new Media.FourCC("MPQ\x1A"); Ibasa.Media.FourCC mpqb = new Media.FourCC("MPQ\x1B"); //find offset var fourcc = Reader.Read <Ibasa.Media.FourCC>(); founda = fourcc == mpqa; foundb = fourcc == mpqb; while (!founda && !foundb) { offset += 512; fourcc = Reader.Read <Ibasa.Media.FourCC>(); founda = fourcc == mpqa; foundb = fourcc == mpqb; } } if (foundb) { var userdatasize = Reader.ReadUInt32(); offset += Reader.ReadUInt32(); var userdataheader = Reader.ReadUInt32(); } Reader.Seek(offset, SeekOrigin.Begin); if (Reader.Read <Media.FourCC>() != new Media.FourCC("MPQ\x1A")) { throw new Exception("WTF"); } HeaderSize = Reader.ReadUInt32(); ArchiveSize = Reader.ReadUInt32(); FormatVersion = Reader.ReadUInt16(); BlockSize = Reader.ReadUInt16(); HashTablePos = Reader.ReadUInt32(); BlockTablePos = Reader.ReadUInt32(); HashTableSize = Reader.ReadUInt32(); BlockTableSize = Reader.ReadUInt32(); if (FormatVersion >= 2) { HiBlockTablePos64 = Reader.ReadUInt64(); HashTablePosHi = Reader.ReadUInt16(); BlockTablePosHi = Reader.ReadUInt16(); } if (FormatVersion >= 3) { ArchiveSize64 = Reader.ReadUInt64(); BetTablePos64 = Reader.ReadUInt64(); HetTablePos64 = Reader.ReadUInt64(); } if (FormatVersion >= 4) { hashtablesize64 = Reader.ReadUInt64(); blocktablesize64 = Reader.ReadUInt64(); hiblocktablesize64 = Reader.ReadUInt64(); hettablesize64 = Reader.ReadUInt64(); bettablesize64 = Reader.ReadUInt64(); dawchunksize = Reader.ReadUInt32(); md5_blocktable = Reader.ReadBytes(16); md5_hashtable = Reader.ReadBytes(16); md5_hiblocktable = Reader.ReadBytes(16); md5_bettable = Reader.ReadBytes(16); md5_hettable = Reader.ReadBytes(16); md5_mpqheader = Reader.ReadBytes(16); } if (HetTablePos64 != 0) { ParseHET(); } if (BetTablePos64 != 0) { ParseBET(); } }
/// <summary> /// Reads a <see cref="Vector8us"/> from an <see cref="Ibasa.IO.BinaryReader">. /// </summary> public static Vector8us ReadVector8us(this Ibasa.IO.BinaryReader reader) { return(new Vector8us(reader.ReadUInt16(), reader.ReadUInt16(), reader.ReadUInt16(), reader.ReadUInt16(), reader.ReadUInt16(), reader.ReadUInt16(), reader.ReadUInt16(), reader.ReadUInt16())); }
public Bsp(Stream stream, IEnumerable<Package.Wad> wads) { if (!stream.CanSeek || !stream.CanRead) throw new ArgumentException("stream must be seekable and readable.", "stream"); if (wads == null) wads = System.Linq.Enumerable.Empty<Package.Wad>(); Reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); if (Reader.ReadUInt32() != 30) throw new InvalidDataException("Version is not 30."); long entitiesOffset = Reader.ReadUInt32(); long entitiesCount = Reader.ReadUInt32(); long planesOffset = Reader.ReadUInt32(); long planesCount = Reader.ReadUInt32(); long texturesOffset = Reader.ReadUInt32(); long texturesCount = Reader.ReadUInt32(); long vertexesOffset = Reader.ReadUInt32(); long vertexesCount = Reader.ReadUInt32(); long visibilityOffset = Reader.ReadUInt32(); long visibilityCount = Reader.ReadUInt32(); long nodesOffset = Reader.ReadUInt32(); long nodesCount = Reader.ReadUInt32(); long texinfoOffset = Reader.ReadUInt32(); long texinfoCount = Reader.ReadUInt32(); long facesOffset = Reader.ReadUInt32(); long facesCount = Reader.ReadUInt32(); long lightingOffset = Reader.ReadUInt32(); long lightingCount = Reader.ReadUInt32(); long clipnodesOffset = Reader.ReadUInt32(); long clipnodesCount = Reader.ReadUInt32(); long leafsOffset = Reader.ReadUInt32(); long leafsCount = Reader.ReadUInt32(); long marksurfacesOffset = Reader.ReadUInt32(); long marksurfacesCount = Reader.ReadUInt32(); long edgesOffset = Reader.ReadUInt32(); long edgesCount = Reader.ReadUInt32(); long surfedgesOffset = Reader.ReadUInt32(); long surfedgesCount = Reader.ReadUInt32(); long modelsOffset = Reader.ReadUInt32(); long modelsCount = Reader.ReadUInt32(); //Entities Reader.Seek(entitiesOffset, SeekOrigin.Begin); Entities = Encoding.ASCII.GetString(Reader.ReadBytes((int)entitiesCount)); //Planes Reader.Seek(planesOffset, SeekOrigin.Begin); Planes = new Planef[planesCount / 20]; for (int i = 0; i < Planes.Length; ++i) { Planes[i] = new Planef( Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()); uint type = Reader.ReadUInt32(); } //Textures { Reader.Seek(texturesOffset, SeekOrigin.Begin); long[] offsets = new long[Reader.ReadUInt32()]; for (int i = 0; i < offsets.Length; ++i) { offsets[i] = Reader.ReadUInt32(); } Textures = new Resource[offsets.Length]; for (int i = 0; i < offsets.Length; ++i) { Reader.Seek(texturesOffset + offsets[i], SeekOrigin.Begin); string name = Encoding.ASCII.GetString(Reader.ReadBytes(16)); int nullbyte = name.IndexOf('\0'); name = nullbyte == -1 ? name : name.Substring(0, nullbyte); int width = Reader.ReadInt32(); int height = Reader.ReadInt32(); long[] dataoffsets = new long[4]; dataoffsets[0] = Reader.ReadUInt32(); dataoffsets[1] = Reader.ReadUInt32(); dataoffsets[2] = Reader.ReadUInt32(); dataoffsets[3] = Reader.ReadUInt32(); Resource resource = null; if (dataoffsets.All(o => o == 0)) { foreach (var wad in wads) { resource = wad[name]; if (resource != null) { break; } } } else { resource = new Resource(new Size3i(width, height, 1), 4, 1, Format.R8G8B8A8UNorm); byte[][] images = new byte[4][]; for (int mipSlice = 0; mipSlice < 4; ++mipSlice) { Reader.Seek(texturesOffset + offsets[i] + dataoffsets[mipSlice], SeekOrigin.Begin); images[mipSlice] = Reader.ReadBytes(width * height); width >>= 1; height >>= 1; } Reader.Seek(2, SeekOrigin.Current); byte[] pallet = Reader.ReadBytes(256 * 3); for (int mipSlice = 0; mipSlice < 4; ++mipSlice) { byte[] data = resource[mipSlice, 0]; byte[] image = images[mipSlice]; for (int j = 0; j < image.Length; ++j) { int palletIndex = image[j] * 3; int dataIndex = j * 3; data[dataIndex + 0] = pallet[palletIndex + 0]; data[dataIndex + 1] = pallet[palletIndex + 1]; data[dataIndex + 2] = pallet[palletIndex + 2]; } } } Textures[i] = resource; } } //Vertices Reader.Seek(vertexesOffset, SeekOrigin.Begin); Vertices = new Vector3f[vertexesCount / 12]; for (int i = 0; i < Vertices.Length; ++i) { Vertices[i] = new Vector3f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()); } //Visibility Reader.Seek(visibilityOffset, SeekOrigin.Begin); Visibility = Reader.ReadBytes((int)visibilityCount); //Nodes //Surfaces Reader.Seek(texinfoOffset, SeekOrigin.Begin); Surfaces = new Surface[texinfoCount / 24]; for (int i = 0; i < Surfaces.Length; ++i) { Surfaces[i] = new Surface( new Vector4f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()), new Vector4f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()), Reader.ReadInt32(), Reader.ReadInt32()); } //Faces Reader.Seek(facesOffset, SeekOrigin.Begin); Faces = new Face[facesCount / 20]; for (int i = 0; i < Faces.Length; ++i) { Faces[i] = new Face( Reader.ReadUInt16(), Reader.ReadInt16(), Reader.ReadInt32(), Reader.ReadInt16(), Reader.ReadInt16(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadInt32()); } //Lighting Reader.Seek(facesOffset, SeekOrigin.Begin); Lighting = Reader.ReadBytes((int)lightingCount); //#define clipnodes 9 //#define leafs 10 //#define marksurfaces 11 //#define edges 12 //#define surfedges 13 //#define models 14 //Edges Reader.Seek(edgesOffset, SeekOrigin.Begin); Edges = new Edge[edgesCount / 4]; for (int i = 0; i < Edges.Length; ++i) { Edges[i] = new Edge(Reader.ReadUInt16(), Reader.ReadUInt16()); } //SurfaceEdges Reader.Seek(surfedgesOffset, SeekOrigin.Begin); SurfaceEdges = new int[surfedgesCount / 4]; for (int i = 0; i < Planes.Length; ++i) { SurfaceEdges[i] = Reader.ReadInt32(); } }
private void ReadExtension(Ibasa.IO.BinaryReader reader) { int size = reader.ReadUInt16(); if (size < 495) //size can grow with new versions { return; } Extension.AuthorName = reader.ReadBytes(41); Extension.AuthorComments = reader.ReadBytes(324); Extension.DateTimeStampMonth = reader.ReadUInt16(); Extension.DateTimeStampDay = reader.ReadUInt16(); Extension.DateTimeStampYear = reader.ReadUInt16(); Extension.DateTimeStampHour = reader.ReadUInt16(); Extension.DateTimeStampMinute = reader.ReadUInt16(); Extension.DateTimeStampSecond = reader.ReadUInt16(); Extension.JobId = reader.ReadBytes(41); Extension.JobTimeHours = reader.ReadUInt16(); Extension.JobTimeMinutes = reader.ReadUInt16(); Extension.JobTimeSeconds = reader.ReadUInt16(); Extension.SoftwareId = reader.ReadBytes(41); Extension.SoftwareVersionNumber = reader.ReadUInt16(); Extension.SoftwareVersionLetter = reader.ReadByte(); Extension.KeyColor = reader.ReadInt32(); Extension.PixelAspectRatioN = reader.ReadUInt16(); Extension.PixelAspectRatioD = reader.ReadUInt16(); Extension.GammaValueN = reader.ReadUInt16(); Extension.GammaValueD = reader.ReadUInt16(); long colorCorrectionOffset = reader.ReadUInt32(); long postageStampOffset = reader.ReadUInt32(); long scanLineOffset = reader.ReadUInt32(); Extension.Attributes = reader.ReadByte(); //read color correction if (colorCorrectionOffset != 0) { reader.BaseStream.Seek(colorCorrectionOffset, SeekOrigin.Begin); Extension.ColorCorrection = new Vector4i[256]; for (int i = 0; i < 256; ++i) { int a = reader.ReadUInt16(); int r = reader.ReadUInt16(); int g = reader.ReadUInt16(); int b = reader.ReadUInt16(); Extension.ColorCorrection[i] = new Vector4i(r, g, b, a); } } //read scan lines if (scanLineOffset != 0) { reader.BaseStream.Seek(scanLineOffset, SeekOrigin.Begin); Extension.ScanLines = new long[Header.Height]; for (int i = 0; i < Header.Height; ++i) { Extension.ScanLines[i] = reader.ReadUInt32(); } } //read postage stamp if (postageStampOffset != 0) { reader.BaseStream.Seek(postageStampOffset, SeekOrigin.Begin); int width = reader.ReadByte(); int height = reader.ReadByte(); Extension.PostageStamp = ReadData(reader, width, height); } }
private Resource ReadUncompressedColorData(Ibasa.IO.BinaryReader reader, int width, int height) { switch (Header.PixelDepth) { case 16: { Resource resource = new Resource(new Size3i(width, height, 1), 1, 1, SharpIL.Format.B8G8R8UNorm); byte[] data = resource[0, 0]; for (int y = 0; y < resource.Size.Height; ++y) { for (int x = 0; x < resource.Size.Width; ++x) { ushort color = reader.ReadUInt16(); byte r = (byte)(color & 0x1F); byte g = (byte)((color >> 5) & 0x1F); byte b = (byte)((color >> 10) & 0x1F); int offset = x * 3 + y * 3 * resource.Size.Width; data[offset + 0] = b; data[offset + 1] = g; data[offset + 2] = r; } } return(resource); } case 24: { Resource resource = new Resource(new Size3i(width, height, 1), 1, 1, SharpIL.Format.B8G8R8UNorm); byte[] data = resource[0, 0]; for (int y = 0; y < resource.Size.Height; ++y) { for (int x = 0; x < resource.Size.Width; ++x) { byte b = reader.ReadByte(); byte g = reader.ReadByte(); byte r = reader.ReadByte(); int offset = x * 3 + y * 3 * resource.Size.Width; data[offset + 0] = b; data[offset + 1] = g; data[offset + 2] = r; } } return(resource); } case 32: { Resource resource = new Resource(new Size3i(width, height, 1), 1, 1, SharpIL.Format.B8G8R8A8UNorm); byte[] data = resource[0, 0]; for (int y = 0; y < resource.Size.Height; ++y) { for (int x = 0; x < resource.Size.Width; ++x) { byte b = reader.ReadByte(); byte g = reader.ReadByte(); byte r = reader.ReadByte(); byte a = reader.ReadByte(); int offset = x * 4 + y * 4 * resource.Size.Width; data[offset + 0] = b; data[offset + 1] = g; data[offset + 2] = r; data[offset + 3] = a; } } return(resource); } default: throw new InvalidDataException("Unrecognized image depth."); } }
public Bsp(Stream stream, IEnumerable <Package.Wad> wads) { if (!stream.CanSeek || !stream.CanRead) { throw new ArgumentException("stream must be seekable and readable.", "stream"); } if (wads == null) { wads = System.Linq.Enumerable.Empty <Package.Wad>(); } Reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); if (Reader.ReadUInt32() != 30) { throw new InvalidDataException("Version is not 30."); } long entitiesOffset = Reader.ReadUInt32(); long entitiesCount = Reader.ReadUInt32(); long planesOffset = Reader.ReadUInt32(); long planesCount = Reader.ReadUInt32(); long texturesOffset = Reader.ReadUInt32(); long texturesCount = Reader.ReadUInt32(); long vertexesOffset = Reader.ReadUInt32(); long vertexesCount = Reader.ReadUInt32(); long visibilityOffset = Reader.ReadUInt32(); long visibilityCount = Reader.ReadUInt32(); long nodesOffset = Reader.ReadUInt32(); long nodesCount = Reader.ReadUInt32(); long texinfoOffset = Reader.ReadUInt32(); long texinfoCount = Reader.ReadUInt32(); long facesOffset = Reader.ReadUInt32(); long facesCount = Reader.ReadUInt32(); long lightingOffset = Reader.ReadUInt32(); long lightingCount = Reader.ReadUInt32(); long clipnodesOffset = Reader.ReadUInt32(); long clipnodesCount = Reader.ReadUInt32(); long leafsOffset = Reader.ReadUInt32(); long leafsCount = Reader.ReadUInt32(); long marksurfacesOffset = Reader.ReadUInt32(); long marksurfacesCount = Reader.ReadUInt32(); long edgesOffset = Reader.ReadUInt32(); long edgesCount = Reader.ReadUInt32(); long surfedgesOffset = Reader.ReadUInt32(); long surfedgesCount = Reader.ReadUInt32(); long modelsOffset = Reader.ReadUInt32(); long modelsCount = Reader.ReadUInt32(); //Entities Reader.Seek(entitiesOffset, SeekOrigin.Begin); Entities = Encoding.ASCII.GetString(Reader.ReadBytes((int)entitiesCount)); //Planes Reader.Seek(planesOffset, SeekOrigin.Begin); Planes = new Planef[planesCount / 20]; for (int i = 0; i < Planes.Length; ++i) { Planes[i] = new Planef( Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()); uint type = Reader.ReadUInt32(); } //Textures { Reader.Seek(texturesOffset, SeekOrigin.Begin); long[] offsets = new long[Reader.ReadUInt32()]; for (int i = 0; i < offsets.Length; ++i) { offsets[i] = Reader.ReadUInt32(); } Textures = new Resource[offsets.Length]; for (int i = 0; i < offsets.Length; ++i) { Reader.Seek(texturesOffset + offsets[i], SeekOrigin.Begin); string name = Encoding.ASCII.GetString(Reader.ReadBytes(16)); int nullbyte = name.IndexOf('\0'); name = nullbyte == -1 ? name : name.Substring(0, nullbyte); int width = Reader.ReadInt32(); int height = Reader.ReadInt32(); long[] dataoffsets = new long[4]; dataoffsets[0] = Reader.ReadUInt32(); dataoffsets[1] = Reader.ReadUInt32(); dataoffsets[2] = Reader.ReadUInt32(); dataoffsets[3] = Reader.ReadUInt32(); Resource resource = null; if (dataoffsets.All(o => o == 0)) { foreach (var wad in wads) { resource = wad[name]; if (resource != null) { break; } } } else { resource = new Resource(new Size3i(width, height, 1), 4, 1, Format.R8G8B8A8UNorm); byte[][] images = new byte[4][]; for (int mipSlice = 0; mipSlice < 4; ++mipSlice) { Reader.Seek(texturesOffset + offsets[i] + dataoffsets[mipSlice], SeekOrigin.Begin); images[mipSlice] = Reader.ReadBytes(width * height); width >>= 1; height >>= 1; } Reader.Seek(2, SeekOrigin.Current); byte[] pallet = Reader.ReadBytes(256 * 3); for (int mipSlice = 0; mipSlice < 4; ++mipSlice) { byte[] data = resource[mipSlice, 0]; byte[] image = images[mipSlice]; for (int j = 0; j < image.Length; ++j) { int palletIndex = image[j] * 3; int dataIndex = j * 3; data[dataIndex + 0] = pallet[palletIndex + 0]; data[dataIndex + 1] = pallet[palletIndex + 1]; data[dataIndex + 2] = pallet[palletIndex + 2]; } } } Textures[i] = resource; } } //Vertices Reader.Seek(vertexesOffset, SeekOrigin.Begin); Vertices = new Vector3f[vertexesCount / 12]; for (int i = 0; i < Vertices.Length; ++i) { Vertices[i] = new Vector3f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()); } //Visibility Reader.Seek(visibilityOffset, SeekOrigin.Begin); Visibility = Reader.ReadBytes((int)visibilityCount); //Nodes //Surfaces Reader.Seek(texinfoOffset, SeekOrigin.Begin); Surfaces = new Surface[texinfoCount / 24]; for (int i = 0; i < Surfaces.Length; ++i) { Surfaces[i] = new Surface( new Vector4f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()), new Vector4f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()), Reader.ReadInt32(), Reader.ReadInt32()); } //Faces Reader.Seek(facesOffset, SeekOrigin.Begin); Faces = new Face[facesCount / 20]; for (int i = 0; i < Faces.Length; ++i) { Faces[i] = new Face( Reader.ReadUInt16(), Reader.ReadInt16(), Reader.ReadInt32(), Reader.ReadInt16(), Reader.ReadInt16(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadInt32()); } //Lighting Reader.Seek(facesOffset, SeekOrigin.Begin); Lighting = Reader.ReadBytes((int)lightingCount); //#define clipnodes 9 //#define leafs 10 //#define marksurfaces 11 //#define edges 12 //#define surfedges 13 //#define models 14 //Edges Reader.Seek(edgesOffset, SeekOrigin.Begin); Edges = new Edge[edgesCount / 4]; for (int i = 0; i < Edges.Length; ++i) { Edges[i] = new Edge(Reader.ReadUInt16(), Reader.ReadUInt16()); } //SurfaceEdges Reader.Seek(surfedgesOffset, SeekOrigin.Begin); SurfaceEdges = new int[surfedgesCount / 4]; for (int i = 0; i < Planes.Length; ++i) { SurfaceEdges[i] = Reader.ReadInt32(); } }