protected void RecalculateSoundAssetSize(int i, SoundAsset asi) { SoundAsset nearest = null; for (int j = 0; j < Assets.Length; j++) { if (j == i) { continue; } Asset aj = Assets[j]; if (aj.Type != AssetType.SOUND) { continue; } SoundAsset asj = (SoundAsset)aj; if (!asj.StoredExternally) { continue; } if (asj.SoundOffset >= asi.SoundEnd) { if (asj.SoundOffset == asi.SoundEnd) { nearest = asj; break; } if (nearest == null) { nearest = asj; } else if (nearest.SoundOffset > asj.SoundOffset) { nearest = asj; } } } if ((nearest != null) && (nearest.SoundOffset != UInt32.MaxValue)) { if (asi.SoundEnd != nearest.SoundOffset) { asi.SoundEnd = nearest.SoundOffset; } } }
protected void RecalculateSoundSizes() { for (int i = 0; i < Assets.Length; i++) { Asset ai = Assets[i]; if (ai.Type != AssetType.SOUND) { continue; } SoundAsset asi = (SoundAsset)ai; if (!asi.StoredExternally) { continue; } RecalculateSoundAssetSize(i, asi); } }
protected void Extract(Asset asset, Stream outStream) { FileStream stream; if (asset.Type == AssetType.SOUND) { SoundAsset soundAsset = (SoundAsset)asset; if (soundAsset.StoredExternally) { stream = File.OpenRead(fileSound); try { stream.Position = soundAsset.SoundOffset; Extract(stream, outStream, soundAsset.SoundLength); return; } finally { stream.Close(); } } } stream = File.OpenRead(file); try { stream.Position = BeginningOfData + asset.Offset + asset.HeaderLength; UInt32 length = asset.ActualSize; switch (asset.Type) { case AssetType.TEXT: // Text files are length prefixed. stream.Position += 4; length -= 4; break; case AssetType.SOUND: if (asset.ActualSize > 24) { stream.Position += 20; length -= 20; if (!CheckAudioHeader(stream)) { throw new Exception("Invalid sound format"); } } break; default: break; } asset.Extract(stream, outStream, length); } finally { stream.Dispose(); } }
public AssetFile(string file) { this.file = file; this.fileSound = file + ".resS"; if (!File.Exists(fileSound)) { fileSound = null; } FileStream stream = File.OpenRead(file); try { BinaryReader reader = new BinaryReader(stream); UInt32 assetCount; HeaderLength = ReverseBytes(reader.ReadUInt32()); FileSize = ReverseBytes(reader.ReadUInt32()); Unknown2 = ReverseBytes(reader.ReadUInt32()); BeginningOfData = ReverseBytes(reader.ReadUInt32()); Unknown4 = reader.ReadUInt32(); Version = Encoding.UTF8.GetString(reader.ReadBytes(8)).Trim('\0'); Unknown5 = reader.ReadUInt32(); Unknown6 = reader.ReadUInt32(); Unknown7 = reader.ReadUInt32(); assetCount = reader.ReadUInt32(); Assets = new Asset[assetCount]; for (int index = 0; index < assetCount; index++) { Assets[index] = new Asset(reader); switch (Assets[index].Type) { case AssetType.SOUND: Assets[index] = new SoundAsset(Assets[index]); break; case AssetType.TEXTURE: Assets[index] = new TextureAsset(Assets[index]); break; default: break; } } foreach (Asset asset in Assets) { if (asset.Type == (AssetType)1) { asset.Name = ""; continue; } stream.Position = BeginningOfData + asset.Offset; //******************* //* Read the name //******************* reader = new BinaryReader(stream); UInt32 nameLength = reader.ReadUInt32(); asset.Name = Encoding.UTF8.GetString(reader.ReadBytes((int)nameLength)); if (nameLength % 4 == 0) { asset.HeaderLength = 4 + nameLength; } else { asset.HeaderLength = 4 + nameLength + (4 - (nameLength % 4)); } //************************** //* Parse the sound header //************************** if (asset.Type == AssetType.SOUND) { stream.Position = BeginningOfData + asset.Offset + asset.HeaderLength; SoundAsset soundAsset = (SoundAsset)asset; reader = new BinaryReader(stream); soundAsset.SoundUnknown0 = reader.ReadUInt32(); soundAsset.SoundUnknown1 = reader.ReadUInt32(); soundAsset.SoundUnknown2 = reader.ReadUInt32(); soundAsset.SoundType = reader.ReadUInt32(); soundAsset.SoundLength = reader.ReadUInt32(); if (soundAsset.ActualSize == 24) { soundAsset.SoundOffset = reader.ReadUInt32(); } } //************************** //* Parse the texture header //************************** if (asset.Type == AssetType.TEXTURE) { stream.Position = BeginningOfData + asset.Offset + asset.HeaderLength; ((TextureAsset)asset).Parse(stream); } } } finally { stream.Dispose(); } RecalculateSoundSizes(); }