private NTROStruct ReadStructure(ResourceIntrospectionManifest.ResourceDiskStruct refStruct, long startingOffset) { var structEntry = new NTROStruct(refStruct.Name); foreach (var field in refStruct.FieldIntrospection) { Reader.BaseStream.Position = startingOffset + field.OnDiskOffset; ReadFieldIntrospection(field, ref structEntry); } // Some structs are padded, so all the field sizes do not add up to the size on disk Reader.BaseStream.Position = startingOffset + refStruct.DiskSize; if (refStruct.BaseStructId != 0) { var previousOffset = Reader.BaseStream.Position; var newStruct = Resource.IntrospectionManifest.ReferencedStructs.First(x => x.Id == refStruct.BaseStructId); // Valve doesn't print this struct's type, so we can't just call ReadStructure *sigh* foreach (var field in newStruct.FieldIntrospection) { Reader.BaseStream.Position = startingOffset + field.OnDiskOffset; ReadFieldIntrospection(field, ref structEntry); } Reader.BaseStream.Position = previousOffset; } return(structEntry); }
private void ReadStructure(ResourceIntrospectionManifest.ResourceDiskStruct refStruct, long startingOffset) { Writer.WriteLine(refStruct.Name); Writer.WriteLine("{"); Writer.Indent++; foreach (var field in refStruct.FieldIntrospection) { Reader.BaseStream.Position = startingOffset + field.OnDiskOffset; ReadFieldIntrospection(field); } if (refStruct.BaseStructId != 0) { var previousOffset = Reader.BaseStream.Position; var newStruct = Resource.IntrospectionManifest.ReferencedStructs.First(x => x.Id == refStruct.BaseStructId); // Valve doesn't print this struct's type, so we can't just call ReadStructure *sigh* foreach (var field in newStruct.FieldIntrospection) { Reader.BaseStream.Position = startingOffset + field.OnDiskOffset; ReadFieldIntrospection(field); } Reader.BaseStream.Position = previousOffset; } Writer.Indent--; Writer.WriteLine("}"); }
public override void Read(BinaryReader reader, Resource resource) { // NTRO only in version 0? if (resource.IntrospectionManifest == null) { var block = new ResourceIntrospectionManifest.ResourceDiskStruct(); var field = new ResourceIntrospectionManifest.ResourceDiskStruct.Field { FieldName = "m_bitpackedsoundinfo", Type = DataType.UInt32, }; block.FieldIntrospection.Add(field); field = new ResourceIntrospectionManifest.ResourceDiskStruct.Field { FieldName = "m_loopStart", Type = DataType.Int32, OnDiskOffset = 4, }; block.FieldIntrospection.Add(field); field = new ResourceIntrospectionManifest.ResourceDiskStruct.Field { FieldName = "m_flDuration", Type = DataType.Float, OnDiskOffset = 12, }; block.FieldIntrospection.Add(field); resource.Blocks[BlockType.NTRO] = new ResourceIntrospectionManifest(); resource.IntrospectionManifest.ReferencedStructs.Add(block); } reader.BaseStream.Position = Offset; base.Read(reader, resource); LoopStart = ((NTROValue <int>)Output["m_loopStart"]).Value; Duration = ((NTROValue <float>)Output["m_flDuration"]).Value; var bitpackedSoundInfo = ((NTROValue <uint>)Output["m_bitpackedsoundinfo"]).Value; Type = (AudioFileType)ExtractSub(bitpackedSoundInfo, 0, 2); Bits = ExtractSub(bitpackedSoundInfo, 2, 5); Channels = ExtractSub(bitpackedSoundInfo, 7, 2); SampleSize = ExtractSub(bitpackedSoundInfo, 9, 3); AudioFormat = ExtractSub(bitpackedSoundInfo, 12, 2); SampleRate = ExtractSub(bitpackedSoundInfo, 14, 17); if (Type > AudioFileType.MP3) { throw new NotImplementedException($"Unknown audio file format '{Type}', please report this on GitHub."); } }
private const int SIGNATURE = 55987030; // "VKV\x03" aka valve keyvalue, version 3 public override void Read(BinaryReader reader, Resource resource) { if (resource.IntrospectionManifest == null) { var block = new ResourceIntrospectionManifest.ResourceDiskStruct(); var field = new ResourceIntrospectionManifest.ResourceDiskStruct.Field { FieldName = "m_Signature", Count = 1, Type = DataType.Int32 }; block.FieldIntrospection.Add(field); field = new ResourceIntrospectionManifest.ResourceDiskStruct.Field { FieldName = "m_Encoding", Count = 4, OnDiskOffset = 4, Type = DataType.Boolean }; block.FieldIntrospection.Add(field); field = new ResourceIntrospectionManifest.ResourceDiskStruct.Field { FieldName = "m_Format", Count = 4, OnDiskOffset = 20, Type = DataType.Boolean }; block.FieldIntrospection.Add(field); resource.Blocks[BlockType.NTRO] = new ResourceIntrospectionManifest(); resource.IntrospectionManifest.ReferencedStructs.Add(block); } base.Read(reader, resource); reader.BaseStream.Position = Offset; // TODO: Use parsed NTRO data if (reader.ReadUInt32() != SIGNATURE) { throw new InvalidDataException("Wrong signature."); } reader.BaseStream.Position += 32; // encoding + format (guids?) // TODO }
public override void Read(BinaryReader reader, Resource resource) { // NTRO only in version 0? if (resource.IntrospectionManifest == null) { var block = new ResourceIntrospectionManifest.ResourceDiskStruct(); var field = new ResourceIntrospectionManifest.ResourceDiskStruct.Field { FieldName = "m_bitpackedsoundinfo", Type = DataType.UInt32, }; block.FieldIntrospection.Add(field); field = new ResourceIntrospectionManifest.ResourceDiskStruct.Field { FieldName = "m_loopStart", Type = DataType.Int32, OnDiskOffset = 4, }; block.FieldIntrospection.Add(field); field = new ResourceIntrospectionManifest.ResourceDiskStruct.Field { FieldName = "m_flDuration", Type = DataType.Float, OnDiskOffset = 12, }; block.FieldIntrospection.Add(field); resource.Blocks.Add(new ResourceIntrospectionManifest()); resource.IntrospectionManifest.ReferencedStructs.Add(block); } reader.BaseStream.Position = Offset; base.Read(reader, resource); LoopStart = ((NTROValue <int>)Output["m_loopStart"]).Value; Duration = ((NTROValue <float>)Output["m_flDuration"]).Value; var bitpackedSoundInfo = ((NTROValue <uint>)Output["m_bitpackedsoundinfo"]).Value; // If these 5 bits are 0, it is the new format instead of the old if (ExtractSub(bitpackedSoundInfo, 27, 5) == 0) { // New format SampleRate = ExtractSub(bitpackedSoundInfo, 0, 16); SoundType = GetTypeFromNewFormat(ExtractSub(bitpackedSoundInfo, 16, 2)); // unknown = ExtractSub(bitpackedSoundInfo, 18, 2); Bits = ExtractSub(bitpackedSoundInfo, 20, 7); SampleSize = Bits / 8; Channels = 1; AudioFormat = 1; } else { // Old format SoundType = (AudioFileType)ExtractSub(bitpackedSoundInfo, 0, 2); Bits = ExtractSub(bitpackedSoundInfo, 2, 5); Channels = ExtractSub(bitpackedSoundInfo, 7, 2); SampleSize = ExtractSub(bitpackedSoundInfo, 9, 3); AudioFormat = ExtractSub(bitpackedSoundInfo, 12, 2); SampleRate = ExtractSub(bitpackedSoundInfo, 14, 17); } if (SoundType > AudioFileType.MP3) { throw new NotImplementedException($"Unknown audio file format '{SoundType}', please report this on GitHub."); } }