private void ReadHeader(Ibasa.IO.BinaryReader reader) { HeaderFlags = (HeaderFlagsEnum)reader.ReadInt32(); Height = reader.ReadInt32(); Width = reader.ReadInt32(); Pitch = reader.ReadInt32(); Depth = reader.ReadInt32(); MipmapCount = reader.ReadInt32(); reader.ReadBytes(44); //skip padding int pixelSize = reader.ReadInt32(); if (pixelSize != 32) { throw new InvalidDataException(string.Format("Pixel format size {0} does not match 32.", pixelSize)); } PixelFlags = (PixelFlagsEnum)reader.ReadInt32(); FourCC = new FourCC(reader.ReadInt32()); RGBBitCount = reader.ReadInt32(); RBitMask = reader.ReadInt32(); GBitMask = reader.ReadInt32(); BBitMask = reader.ReadInt32(); ABitMask = reader.ReadInt32(); SurfaceFlags = (SurfaceFlagsEnum)reader.ReadInt32(); CubemapFlags = (CubemapFlagsEnum)reader.ReadInt32(); reader.ReadBytes(12); //skip padding }
private void ReadHeader73(Ibasa.IO.BinaryReader reader) { if (VersionMinor >= 3) { reader.ReadBytes(3); //skip padding int resourceCount = reader.ReadInt32(); reader.ReadBytes(8); //skip padding var resources = new Resource[resourceCount]; for (int res = 0; res < resourceCount; ++res) { int type = reader.ReadInt32(); resources[res] = new Resource( (ResourceType)type & ResourceType.Mask, (ResourceFlags)type & ResourceFlags.Mask, reader.ReadInt32()); } Resources = new ImmutableArray <Resource>(resources); } else if (VersionMinor == 2) { //skip padding reader.ReadBytes(15); //skip padding Resources = new ImmutableArray <Resource>(0); } }
ImmutableArray <BodyPart> LoadBodyParts(Ibasa.IO.BinaryReader reader, int count) { long offset = reader.BaseStream.Position; BodyPart[] bodyParts = new BodyPart[count]; for (int i = 0; i < count; ++i) { reader.BaseStream.Position = offset; long nameOffset = offset + reader.ReadInt32(); int modelCount = reader.ReadInt32(); int @base = reader.ReadInt32(); long modelOffset = offset + reader.ReadInt32(); offset = reader.BaseStream.Position; reader.BaseStream.Position = nameOffset; string name = LoadString(reader); reader.BaseStream.Position = modelOffset; ImmutableArray <Model> models = LoadModels(reader, modelCount); bodyParts[i] = new BodyPart(name, @base, models); } return(new ImmutableArray <BodyPart>(bodyParts)); }
private Resource ReadData(Ibasa.IO.BinaryReader reader, int width, int height) { if (Header.ImageType == 0) { return(null); } switch (Header.ImageType) { case 1: return(ReadUncompressedMappedData(reader, width, height)); case 2: return(ReadUncompressedColorData(reader, width, height)); case 3: return(ReadUncompressedBWData(reader, width, height)); case 5: return(ReadRLEMappedData(reader, width, height)); case 10: return(ReadRLEColorData(reader, width, height)); case 11: return(ReadRLEBWData(reader, width, height)); default: throw new InvalidDataException("Unrecognized image type."); } }
private Resource ReadUncompressedMappedData(Ibasa.IO.BinaryReader reader, int width, int height) { switch (Header.PixelDepth) { case 8: { 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) { uint color = ColorMap[reader.ReadByte()]; int offset = x * 4 + y * 4 * resource.Size.Width; data[offset + 0] = (byte)(color & 0xFF); data[offset + 1] = (byte)((color >> 8) & 0xFF); data[offset + 2] = (byte)((color >> 16) & 0xFF); data[offset + 3] = (byte)((color >> 24) & 0xFF); } } return(resource); } default: throw new InvalidDataException("Unrecognized image depth."); } }
ImmutableArray <Texture> LoadTextures(Ibasa.IO.BinaryReader reader, int count) { long offset = reader.BaseStream.Position; Texture[] textures = new Texture[count]; for (int i = 0; i < count; ++i) { reader.BaseStream.Position = offset; long nameOffset = offset + reader.ReadInt32(); int flags = reader.ReadInt32(); int used = reader.ReadInt32(); int unused = reader.ReadInt32(); reader.Seek(12 * 4, SeekOrigin.Current); //skip 12 ints offset = reader.BaseStream.Position; reader.BaseStream.Position = nameOffset; string name = LoadString(reader); textures[i] = new Texture(name, flags); } return(new ImmutableArray <Texture>(textures)); }
ImmutableArray <HitBox> LoadHitBoxes(Ibasa.IO.BinaryReader reader, int count) { long offset = reader.BaseStream.Position; HitBox[] hitBoxes = new HitBox[count]; for (int i = 0; i < count; ++i) { reader.BaseStream.Position = offset; int bone = reader.ReadInt32(); int group = reader.ReadInt32(); Boxf box = new Boxf( new Point3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()), new Size3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); long nameOffset = offset + reader.ReadInt32(); reader.Seek(8 * 4, SeekOrigin.Current); //skip 8 ints offset = reader.BaseStream.Position; reader.BaseStream.Position = nameOffset; string name = LoadString(reader); hitBoxes[i] = new HitBox(bone, group, box, name); } return(new ImmutableArray <HitBox>(hitBoxes)); }
private Resource ReadUncompressedBWData(Ibasa.IO.BinaryReader reader, int width, int height) { switch (Header.PixelDepth) { case 8: { Resource resource = new Resource(new Size3i(width, height, 1), 1, 1, SharpIL.Format.A8UNorm); byte[] data = resource[0, 0]; for (int y = 0; y < resource.Size.Height; ++y) { for (int x = 0; x < resource.Size.Width; ++x) { byte color = reader.ReadByte(); int offset = x + y * resource.Size.Width; data[offset] = color; } } return(resource); } default: throw new InvalidDataException("Unrecognized image depth."); } }
private void ReadFooter(Ibasa.IO.BinaryReader reader) { if (reader.PeekChar() == -1) { return; //end of stream or cant seek no footer possible } reader.BaseStream.Seek(-26, SeekOrigin.End); long extensionOffset = reader.ReadUInt32(); long developerOffset = reader.ReadUInt32(); string signature = new string(reader.ReadChars(18)); if (signature != "TRUEVISION-XFILE.\0") { return; } if (extensionOffset != 0) { reader.BaseStream.Seek(extensionOffset, SeekOrigin.Begin); ReadExtension(reader); } if (developerOffset != 0) { reader.BaseStream.Seek(developerOffset, SeekOrigin.Begin); ReadDeveloper(reader); } }
public void Load(Stream stream) { var reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); string signature = Encoding.ASCII.GetString(reader.ReadBytes(4)); if (signature != "VTF\0") { throw new InvalidDataException("File signature does not match 'VTF'."); } VersionMajor = reader.ReadInt32(); VersionMinor = reader.ReadInt32(); if (VersionMajor != 7 && (VersionMinor < 0 || VersionMinor > 5)) { throw new InvalidDataException(string.Format("File version {0}.{1} does not match 7.0 to 7.5.", VersionMajor, VersionMinor)); } HeaderSize = reader.ReadInt32(); ReadHeader70(reader); ReadHeader72(reader); ReadHeader73(reader); ReadData(reader); }
private void Load(Stream stream) { var reader = new Ibasa.IO.BinaryReader(stream, System.Text.Encoding.ASCII); ReadHeader(reader); ReadColorMap(reader); ImageData = ReadData(reader, Header.Width, Header.Height); ReadFooter(reader); }
/// <summary> /// Reads a <see cref="Polygon2i"/> from an <see cref="Ibasa.IO.BinaryReader">. /// </summary> public static Polygon2i ReadPolygon2i(this Ibasa.IO.BinaryReader reader) { var length = reader.ReadInt32(); var array = new Point2i[length]; for (int i=0; i<length; ++i) { array[i] = reader.ReadPoint2i(); } return new Polygon2i(array); }
string LoadString(Ibasa.IO.BinaryReader reader) { StringBuilder builder = new StringBuilder(); char c; while ((c = reader.ReadChar()) != '\0') { builder.Append(c); } return(builder.ToString()); }
private void ReadData(Ibasa.IO.BinaryReader reader) { LowResImage = new SharpIL.Resource( new Size3i(LowResImageWidth, LowResImageHeight, 1), 1, 1, EncodingFromFormat(LowResImageFormat)); HighResImage = new SharpIL.Resource( new Size3i(Width, Height, Depth), MipmapCount, Frames * Faces, EncodingFromFormat(ImageFormat)); if (VersionMinor < 3) { reader.Read(LowResImage[0, 0], 0, LowResImage[0, 0].Length); for (int mip = MipmapCount - 1; mip >= 0; --mip) { Size3f size = HighResImage.ComputeMipSliceSize(mip); for (int frame = 0; frame < Frames; ++frame) { for (int face = 0; face < Faces; ++face) { int array = face + (Faces * frame); reader.Read( HighResImage[mip, array], 0, HighResImage[mip, array].Length); } } } } else { //low res int lowResOffset = Resources.Find((resource) => resource.Type == ResourceType.LowResImage).Data; reader.Seek((uint)lowResOffset, SeekOrigin.Begin); reader.Read(LowResImage[0, 0], 0, LowResImage[0, 0].Length); //high res int highResOffset = Resources.Find((resource) => resource.Type == ResourceType.Image).Data; reader.Seek((uint)highResOffset, SeekOrigin.Begin); for (int mip = MipmapCount - 1; mip >= 0; --mip) { Size3f size = HighResImage.ComputeMipSliceSize(mip); for (int frame = 0; frame < Frames; ++frame) { for (int face = 0; face < Faces; ++face) { byte[] data = HighResImage[mip, face + (Faces * frame)]; reader.Read(data, 0, data.Length); } } } } }
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 ReadDx10Header(Ibasa.IO.BinaryReader reader) { if (!IsDX10Mode) { return; } DxgiFormat = (DxgiFormat)reader.ReadInt32(); ResourceDimension = (ResourceDimensionEnum)reader.ReadInt32(); MiscFlags = (MiscFlagsEnum)reader.ReadInt32(); ArraySize = reader.ReadInt32(); reader.ReadBytes(4); //skip padding }
ImmutableArray <Eyeball> LoadEyeballs(Ibasa.IO.BinaryReader reader, int count) { long offset = reader.BaseStream.Position; Eyeball[] eyeballs = new Eyeball[count]; for (int i = 0; i < count; ++i) { offset = reader.BaseStream.Position; reader.BaseStream.Position = offset; } return(new ImmutableArray <Eyeball>(eyeballs)); }
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."); } }
ImmutableArray <LocalSequence> LoadLocalSequences(Ibasa.IO.BinaryReader reader, int count) { long offset = reader.BaseStream.Position; LocalSequence[] localSequences = new LocalSequence[count]; for (int i = 0; i < count; ++i) { reader.BaseStream.Position = offset; offset = reader.BaseStream.Position; } return(new ImmutableArray <LocalSequence>(localSequences)); }
ImmutableArray <Bone> LoadBones(Ibasa.IO.BinaryReader reader, int count) { long offset = reader.BaseStream.Position; Bone[] bones = new Bone[count]; for (int i = 0; i < count; ++i) { reader.BaseStream.Position = offset; long nameOffset = offset + reader.ReadInt32(); int parent = reader.ReadInt32(); ImmutableArray <int> boneControllers = new ImmutableArray <int>(new int[] { reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32() }); Vector3f position = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Quaternionf quaternion = new Quaternionf(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector3f rotation = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector3f positionScale = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector3f rotationScale = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Matrix4x4f poseToBone = new Matrix4x4f( reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), 0, 0, 0, 1); Quaternionf alignment = new Quaternionf(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); int flags = reader.ReadInt32(); int procType = reader.ReadInt32(); int procIndex = reader.ReadInt32(); int physicsBone = reader.ReadInt32(); int surfacePropIdx = reader.ReadInt32(); int contents = reader.ReadInt32(); reader.Seek(8 * 4, SeekOrigin.Current); //skip 8 ints offset = reader.BaseStream.Position; reader.BaseStream.Position = nameOffset; string name = LoadString(reader); bones[i] = new Bone(name, parent, boneControllers, position, quaternion, rotation, positionScale, rotationScale, poseToBone, alignment, flags, procType, procIndex, physicsBone, surfacePropIdx, contents); } return(new ImmutableArray <Bone>(bones)); }
ImmutableArray <string> LoadStringTable(Ibasa.IO.BinaryReader reader, int count, long baseOffset) { long[] offsets = new long[count]; for (int i = 0; i < count; ++i) { offsets[i] = baseOffset + reader.ReadInt32(); } string[] strings = new string[count]; for (int i = 0; i < count; ++i) { reader.BaseStream.Position = offsets[i]; strings[i] = LoadString(reader); } return(new ImmutableArray <string>(strings)); }
ImmutableArray <BoneController> LoadBoneControllers(Ibasa.IO.BinaryReader reader, int count) { BoneController[] boneControllers = new BoneController[count]; for (int i = 0; i < count; ++i) { boneControllers[i] = new BoneController( reader.ReadInt32(), (BoneControllerType)reader.ReadInt32(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadInt32(), reader.ReadInt32()); reader.Seek(8 * 4, SeekOrigin.Current); //skip 8 ints } return(new ImmutableArray <BoneController>(boneControllers)); }
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(); }
ImmutableArray <Mesh> LoadMeshes(Ibasa.IO.BinaryReader reader, int count) { long offset = reader.BaseStream.Position; Mesh[] meshes = new Mesh[count]; for (int i = 0; i < count; ++i) { reader.BaseStream.Position = offset; int material = reader.ReadInt32(); int modelIndex = reader.ReadInt32(); int vertexCount = reader.ReadInt32(); int vertexOffset = reader.ReadInt32(); int flexCount = reader.ReadInt32(); long flexOffset = offset + reader.ReadInt32(); int materialType = reader.ReadInt32(); int materialParam = reader.ReadInt32(); int meshId = reader.ReadInt32(); Vector3f center = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); int modelvertexdata = reader.ReadInt32(); int[] numLODVertexes = new int[8]; for (int l = 0; l < 8; ++l) { numLODVertexes[l] = reader.ReadInt32(); } ImmutableArray <int> lods = new ImmutableArray <int>(numLODVertexes); reader.Seek(8 * 4, SeekOrigin.Current); //skip 8 ints offset = reader.BaseStream.Position; reader.BaseStream.Position = flexOffset; ImmutableArray <Flex> flexes = LoadFlexes(reader, flexCount); meshes[i] = new Mesh(material, vertexCount, vertexOffset, flexes, materialType, materialParam, meshId, center, lods); } return(new ImmutableArray <Mesh>(meshes)); }
ImmutableArray <Model> LoadModels(Ibasa.IO.BinaryReader reader, int count) { long offset = reader.BaseStream.Position; Model[] models = new Model[count]; for (int i = 0; i < count; ++i) { reader.BaseStream.Position = offset; string name = Encoding.ASCII.GetString(reader.ReadBytes(64)).Trim('\0'); int type = reader.ReadInt32(); float boundingRadius = reader.ReadSingle(); int meshCount = reader.ReadInt32(); long meshOffset = offset + reader.ReadInt32(); int vertexCount = reader.ReadInt32(); int vertexIndex = reader.ReadInt32(); int tangentIndex = reader.ReadInt32(); int numattachments = reader.ReadInt32(); int attachmentindex = reader.ReadInt32(); int eyeballCount = reader.ReadInt32(); long eyeballOffset = offset + reader.ReadInt32(); int vertexData = reader.ReadInt32(); int indexData = reader.ReadInt32(); reader.Seek(8 * 4, SeekOrigin.Current); //skip 8 ints offset = reader.BaseStream.Position; reader.BaseStream.Position = meshOffset; ImmutableArray <Mesh> meshes = LoadMeshes(reader, meshCount); reader.BaseStream.Position = meshOffset; ImmutableArray <Eyeball> eyeballs = LoadEyeballs(reader, meshCount); models[i] = new Model(name, type, boundingRadius, meshes, vertexCount, vertexIndex, tangentIndex, eyeballs); } return(new ImmutableArray <Model>(models)); }
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); }
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))); } }
ImmutableArray <HitBoxSet> LoadHitBoxSets(Ibasa.IO.BinaryReader reader, int count) { long offset = reader.BaseStream.Position; HitBoxSet[] hitBoxSets = new HitBoxSet[count]; for (int i = 0; i < count; ++i) { reader.BaseStream.Position = offset; long nameOffset = offset + reader.ReadInt32(); int hitBoxCount = reader.ReadInt32(); long hitBoxOffset = offset + reader.ReadInt32(); offset = reader.BaseStream.Position; reader.BaseStream.Position = nameOffset; string name = LoadString(reader); reader.BaseStream.Position = hitBoxOffset; ImmutableArray <HitBox> hitBoxes = LoadHitBoxes(reader, hitBoxCount); hitBoxSets[i] = new HitBoxSet(name, hitBoxes); } return(new ImmutableArray <HitBoxSet>(hitBoxSets)); }
private void ReadData(Ibasa.IO.BinaryReader reader) { int depth = (HeaderFlags.HasFlag(HeaderFlagsEnum.Depth) ? Depth : 1); int mipmapCount = (HeaderFlags.HasFlag(HeaderFlagsEnum.MipmapCount) ? MipmapCount : 1); if (IsDX10Mode) { int arraySize = (CubemapFlags.HasFlag(CubemapFlagsEnum.Cubemap) ? 6 : 1) * ArraySize; Image = new Resource(new Size3i(Width, Height, depth), mipmapCount, arraySize, SelectLoadFormat()); for (int arraySlice = 0; arraySlice < Image.ArraySize; ++arraySlice) { for (int mipSlice = 0; mipSlice < Image.MipLevels; ++mipSlice) { byte[] subresource = Image[mipSlice, arraySlice]; reader.Read(subresource, 0, subresource.Length); } } } else if (PixelFlags.HasFlag(PixelFlagsEnum.FourCC)) { int arraySize = (CubemapFlags.HasFlag(CubemapFlagsEnum.Cubemap) ? 6 : 1); Image = new Resource(new Size3i(Width, Height, depth), mipmapCount, arraySize, SelectLoadFormat()); for (int arraySlice = 0; arraySlice < Image.ArraySize; ++arraySlice) { for (int mipSlice = 0; mipSlice < Image.MipLevels; ++mipSlice) { byte[] subresource = Image[mipSlice, arraySlice]; reader.Read(subresource, 0, subresource.Length); } } } }
private void Load(Stream stream) { var reader = new Ibasa.IO.BinaryReader(stream, System.Text.Encoding.ASCII); FourCC signature = new FourCC(reader.ReadInt32()); if (signature != new FourCC("DDS ")) { throw new InvalidDataException("File signature does not match 'DDS '."); } int headerSize = reader.ReadInt32(); if (headerSize != 124) { throw new InvalidDataException(string.Format("Header size {0} does not match 124.", headerSize)); } ReadHeader(reader); ReadDx10Header(reader); FixupInternalState(); Cubemap = CubemapFlags.HasFlag(CubemapFlagsEnum.Cubemap); ReadData(reader); }
public Gcf(Stream stream) { Reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); { long seek = Reader.Position; uint checksum = Reader.ReadBytes(10 * 4).Aggregate(0U, (sum, value) => sum + value); Reader.Position = seek; if (Reader.ReadUInt32() != 0x00000001) // HeaderVersion Always 0x00000001 { throw new InvalidDataException("Header version mismatch."); } if (Reader.ReadUInt32() != 0x00000001) // MajorVersion Always 0x00000001 { throw new InvalidDataException("Major version mismatch."); } var minor = Reader.ReadInt32(); if (minor != 3 && minor != 5 && minor != 6) { throw new InvalidDataException(string.Format("Minor version mismatch, read {0} expected 3, 5 or 6.", minor)); } GCFVersion = new Version(1, minor); CacheID = Reader.ReadInt32(); LastVersionPlayed = Reader.ReadInt32(); var dummy0 = Reader.ReadUInt32(); var dummy1 = Reader.ReadUInt32(); FileSize = Reader.ReadUInt32(); // Total size of GCF file in bytes. SectorSize = Reader.ReadUInt32(); // Size of each data block in bytes. SectorCount = Reader.ReadUInt32(); // Number of data blocks. if (checksum != Reader.ReadUInt32())// Header checksum. throw new InvalidDataException("Checksum mismatch."); } { long seek = Reader.Position; uint checksum = Reader.Read<uint>(7).Aggregate(0U, (sum, value) => sum + value); Reader.Position = seek; BlockCount = Reader.ReadUInt32(); // Number of data blocks. if (BlockCount != SectorCount) { throw new InvalidDataException("BlockCount does not match SectorCount."); } BlocksUsed = Reader.ReadUInt32(); // Number of data blocks that point to data. var dummy0 = Reader.ReadUInt32(); var dummy1 = Reader.ReadUInt32(); var dummy2 = Reader.ReadUInt32(); var dummy3 = Reader.ReadUInt32(); var dummy4 = Reader.ReadUInt32(); if (checksum != Reader.ReadUInt32()) // Header checksum. throw new InvalidDataException("Checksum mismatch."); } BlockEntryOffset = Reader.Position; //Seek past block entries Reader.Seek(BlockCount * BlockEntry.Size, SeekOrigin.Current); { //FragmentationMapHeader long seek = Reader.Position; uint checksum = Reader.Read<uint>(3).Aggregate(0U, (sum, value) => sum + value); Reader.Position = seek; uint sectorCount = Reader.ReadUInt32(); if (SectorCount != sectorCount) throw new InvalidDataException(); FirstUnusedEntry = Reader.ReadUInt32(); Terminator = Reader.ReadUInt32() == 0 ? 0x0000ffff : 0xffffffff; if (checksum != Reader.ReadUInt32()) // Header checksum. throw new InvalidDataException("Checksum mismatch."); } FragmentationMapEntryOffset = Reader.BaseStream.Position; //Seek past block entries Reader.Seek(BlockCount * 4, SeekOrigin.Current); { //BlockMapHeader if (GCFVersion.Minor <= 5) { uint blockCount = Reader.ReadUInt32(); uint firstBlockEntryIndex = Reader.ReadUInt32(); uint lastBlockEntryIndex = Reader.ReadUInt32(); uint dummy0 = Reader.ReadUInt32(); uint checksum = Reader.ReadUInt32(); //struct BlockMapEntry //{ // public uint PreviousBlockEntryIndex; // The previous block entry. (N/A if == BlockCount.) // public uint NextBlockEntryIndex; // The next block entry. (N/A if == BlockCount.) //} Reader.Seek(blockCount * 8, SeekOrigin.Current); } } { //DirectoryHeader if (Reader.ReadUInt32() != 0x00000004) // HeaderVersion Always 0x00000004 throw new InvalidDataException("Header version mismatch."); if (Reader.ReadUInt32() != CacheID) // CacheID throw new InvalidDataException("CacheID mismatch."); if (Reader.ReadUInt32() != LastVersionPlayed) // LastVersionPlayed throw new InvalidDataException("LastVersionPlayed mismatch."); ItemCount = Reader.ReadUInt32(); //public uint ItemCount; // Number of items in the directory. FileCount = Reader.ReadUInt32(); //public uint FileCount; // Number of files in the directory. var dummy0 = Reader.ReadUInt32(); DirectorySize = Reader.ReadUInt32(); //public uint DirectorySize; // Size of lpGCFDirectoryEntries & lpGCFDirectoryNames & lpGCFDirectoryInfo1Entries & lpGCFDirectoryInfo2Entries & lpGCFDirectoryCopyEntries & lpGCFDirectoryLocalEntries in bytes. NameSize = Reader.ReadUInt32(); //public uint NameSize; // Size of the directory names in bytes. HashTableKeyCount = Reader.ReadUInt32(); //public uint HashTableKeyCount; // Number of Info1 entires. CopyCount = Reader.ReadUInt32(); //public uint CopyCount; // Number of files to copy. LocalCount = Reader.ReadUInt32(); //public uint LocalCount; // Number of files to keep local. var dummy1 = Reader.ReadUInt32(); var dummy2 = Reader.ReadUInt32(); var checksum = Reader.ReadUInt32(); // Header checksum never computes } DirectoryEntryOffset = Reader.BaseStream.Position; Reader.Seek(ItemCount * DirectoryEntry.Size, SeekOrigin.Current); DirectoryNameOffset = Reader.BaseStream.Position; Reader.Seek(NameSize, SeekOrigin.Current); DirectoryInfo1EntryOffset = Reader.BaseStream.Position; Reader.Seek(HashTableKeyCount * DirectoryInfo1Entry.Size, SeekOrigin.Current); DirectoryInfo2EntryOffset = Reader.BaseStream.Position; Reader.Seek(ItemCount * DirectoryInfo2Entry.Size, SeekOrigin.Current); DirectoryCopyEntryOffset = Reader.BaseStream.Position; Reader.Seek(CopyCount * DirectoryCopyEntry.Size, SeekOrigin.Current); DirectoryLocalEntryOffset = Reader.BaseStream.Position; Reader.Seek(LocalCount * DirectoryLocalEntry.Size, SeekOrigin.Current); { //DirectoryMapHeader //public uint Dummy0; //public uint Dummy1; Reader.Seek(8, SeekOrigin.Current); } DirectoryMapEntryOffset = Reader.BaseStream.Position; Reader.Seek(ItemCount * 4, SeekOrigin.Current); { //ChecksumHeader ChecksumMapHeader if (Reader.ReadUInt32() != 0x00000001) // HeaderVersion Always 0x00000001 throw new InvalidDataException(); ChecksumSize = Reader.ReadUInt32(); // Size of LPGCFCHECKSUMHEADER & LPGCFCHECKSUMMAPHEADER & in bytes. if (Reader.ReadUInt32() != 0x14893721) // FormatCode Always 0x14893721 throw new InvalidDataException(); if (Reader.ReadUInt32() != 0x00000001) // Dummy0 Always 0x00000001 throw new InvalidDataException(); ChecksumItemCount = Reader.ReadUInt32(); // Number of file ID entries. ChecksumCount = Reader.ReadUInt32(); // Number of checksums. } ChecksumMapEntryOffset = Reader.BaseStream.Position; Reader.Seek(ChecksumItemCount * ChecksumMapEntry.Size, SeekOrigin.Current); ChecksumEntryOffset = Reader.BaseStream.Position; Reader.Seek(ChecksumCount * 4, SeekOrigin.Current); //Skip past signature Reader.Seek(0x80, SeekOrigin.Current); if (Reader.ReadUInt32() != LastVersionPlayed) // LastVersionPlayed throw new InvalidDataException("LastVersionPlayed mismatch."); { //DataHeader uint checksum = 0; uint sectorCount, sectorSize; checksum += (sectorCount = Reader.ReadUInt32()); // Number of data blocks. if (SectorCount != sectorCount) throw new InvalidDataException(); checksum += (sectorSize = Reader.ReadUInt32()); // Size of each data block in bytes. if (SectorSize != sectorSize) throw new InvalidDataException(); checksum += (FirstSectorOffset = Reader.ReadUInt32()); // Offset to first data block. checksum += (SectorsUsed = Reader.ReadUInt32()); // Number of data blocks that contain data. if (checksum != Reader.ReadUInt32()) //public uint Checksum; // Header checksum. throw new InvalidDataException(); } for (uint index = 0; index < ItemCount; ++index) { DirectoryEntry entry = GetDirectoryEntry(index); if (entry.ParentIndex == 0xFFFFFFFF) { RootDirectory = new GcfDirectoryInfo(this, index); break; } } }
public void Load(Stream stream) { var reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); string signature = Encoding.ASCII.GetString(reader.ReadBytes(4)); if (signature != "VTF\0") throw new InvalidDataException("File signature does not match 'VTF'."); VersionMajor = reader.ReadInt32(); VersionMinor = reader.ReadInt32(); if (VersionMajor != 7 && (VersionMinor < 0 || VersionMinor > 5)) throw new InvalidDataException(string.Format("File version {0}.{1} does not match 7.0 to 7.5.", VersionMajor, VersionMinor)); HeaderSize = reader.ReadInt32(); ReadHeader70(reader); ReadHeader72(reader); ReadHeader73(reader); ReadData(reader); }
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 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 Load(Stream stream) { var reader = new Ibasa.IO.BinaryReader(stream, System.Text.Encoding.ASCII); FourCC signature = new FourCC(reader.ReadInt32()); if (signature != new FourCC("DDS ")) throw new InvalidDataException("File signature does not match 'DDS '."); int headerSize = reader.ReadInt32(); if (headerSize != 124) throw new InvalidDataException(string.Format("Header size {0} does not match 124.", headerSize)); ReadHeader(reader); ReadDx10Header(reader); FixupInternalState(); Cubemap = CubemapFlags.HasFlag(CubemapFlagsEnum.Cubemap); ReadData(reader); }
private void Load(Stream stream) { var reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); long baseOffset = reader.BaseStream.Position; string signature = Encoding.ASCII.GetString(reader.ReadBytes(4)); if (signature != "IDST") throw new InvalidDataException("File signature does not match 'IDST'."); Version = reader.ReadInt32(); if ((Version < 44 || Version > 49)) throw new InvalidDataException(string.Format("File version {0} does not match 44 to 49.", Version)); Checksum = reader.ReadInt32(); Name = Encoding.ASCII.GetString(reader.ReadBytes(64)).Trim('\0'); int length = reader.ReadInt32(); //file length EyePosition = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); IlluminationPosition = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Hull = new Boxf( new Point3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()), new Size3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); ViewHull = new Boxf( new Point3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()), new Size3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); Flags = (MdlFlags)reader.ReadInt32(); int bonesCount = reader.ReadInt32(); long bonesOffset = baseOffset + reader.ReadInt32(); int boneControllersCount = reader.ReadInt32(); long boneControllersOffset = baseOffset + reader.ReadInt32(); int hitBoxSetsCount = reader.ReadInt32(); long hitBoxSetsOffset = baseOffset + reader.ReadInt32(); int localAnimCount = reader.ReadInt32(); long localAnimOffset = baseOffset + reader.ReadInt32(); int localSeqCount = reader.ReadInt32(); long localSeqOffset = baseOffset + reader.ReadInt32(); int activityListVersion = reader.ReadInt32(); int eventsIndexed = reader.ReadInt32(); int texturesCount = reader.ReadInt32(); long texturesOffset = baseOffset + reader.ReadInt32(); int cdTexturesCount = reader.ReadInt32(); long cdTexturesOffset = baseOffset + reader.ReadInt32(); int skinRefsCount = reader.ReadInt32(); int skinFamiliesCount = reader.ReadInt32(); long skinOffset = baseOffset + reader.ReadInt32(); int bodyPartsCount = reader.ReadInt32(); long bodyPartsOffset = baseOffset + reader.ReadInt32(); int localAttachmentsCount = reader.ReadInt32(); long localAttachmentsOffset = baseOffset + reader.ReadInt32(); int localNodesCount = reader.ReadInt32(); long localNodesOffset = baseOffset + reader.ReadInt32(); long localNodesNameOffset = baseOffset + reader.ReadInt32(); int flexDescsCount = reader.ReadInt32(); long flexDescsOffset = baseOffset + reader.ReadInt32(); int flexControllersCount = reader.ReadInt32(); long flexControllersOffset = baseOffset + reader.ReadInt32(); int flexRulesCount = reader.ReadInt32(); long flexRulesOffset = baseOffset + reader.ReadInt32(); int ikChainsCount = reader.ReadInt32(); long ikChainsOffset = baseOffset + reader.ReadInt32(); int mouthsCount = reader.ReadInt32(); long mouthsOffset = baseOffset + reader.ReadInt32(); //=== //Start reading from offsets //=== reader.BaseStream.Position = bonesOffset; Bones = LoadBones(reader, bonesCount); reader.BaseStream.Position = boneControllersOffset; BoneControllers = LoadBoneControllers(reader, boneControllersCount); //reader.BaseStream.Position = hitBoxSetsOffset; //HitBoxSets = LoadHitBoxSets(reader, hitBoxSetsCount); reader.BaseStream.Position = localAnimOffset; LocalAnimations = LoadLocalAnimations(reader, localAnimCount); reader.BaseStream.Position = localSeqOffset; LocalSequences = LoadLocalSequences(reader, localSeqCount); reader.BaseStream.Position = texturesOffset; Textures = LoadTextures(reader, texturesCount); reader.BaseStream.Position = cdTexturesOffset; CdTextures = LoadStringTable(reader, cdTexturesCount, baseOffset); //skin refs //TODO reader.BaseStream.Position = bodyPartsOffset; BodyParts = LoadBodyParts(reader, bodyPartsCount); }