/// <summary> /// /// </summary> /// <param name="loc"></param> public HSDStruct GetStruct(Tuple <int, int> loc) { r.BaseStream.Position = loc.Item1; HSDStruct s = new HSDStruct(r.ReadBytes(loc.Item2)); return(s); }
private void Load(string fileName) { var fileBytes = File.ReadAllBytes(fileName); using (var ms = new MemoryStream(fileBytes)) { using (var reader = new BinaryReaderExt(ms)) { reader.ReadBytes(16); var fileCount = reader.ReadInt32(); reader.ReadInt32(); for (var i = 0; i < fileCount; i++) { var file = new FILE(); file.Index = reader.ReadInt32(); reader.ReadBytes(21); file.FileName = reader.ReadAscii(); file.FileName = file.FileName.Substring(0, file.FileName.IndexOf('\0')); // Otherwise windows will crap out reader.ReadBytes(12); var filePos = reader.ReadInt32(); var fileLength = reader.ReadInt32(); var pos = reader.BaseStream.Position; reader.BaseStream.Seek(filePos, SeekOrigin.Begin); file.File = reader.ReadBytes(fileLength); reader.BaseStream.Seek(pos, SeekOrigin.Begin); Files.Add(file); } } } }
private static bool CanLoadVersion(string path) { Stream s = Open(path); int version; using (BinaryReader br = new BinaryReaderExt(s, Encoding.ASCII, true)) { byte[] magic = br.ReadBytes(4); if (magic.AsString() != MAGIC.AsString()) { throw new FileLoadException("Invalid IRD file", path); } version = br.ReadByte(); } try { s.Close(); } catch (ZlibException) { // Bug in ZLib, it will throw an error when you don't read the whole stream! } return(version == IrdVersion || CompatibleVersions.Any(v => v == version)); }
public RemoteConPacket(byte[] packetBytes, bool useUtf8 = false) { if (useUtf8) { _packetEncoding = Encoding.UTF8; } using (var ms = new MemoryStream(packetBytes)) { using (var reader = new BinaryReaderExt(ms)) { Size = reader.ReadInt32LittleEndian(); // The size field (4-Bytes Little Endian Int) is, according to specification, not included. if (Size + 4 != packetBytes.Length) { throw new LengthMismatchException("packet length mismatch"); } Id = reader.ReadInt32LittleEndian(); var packetType = reader.ReadInt32LittleEndian(); if (!Enum.IsDefined(typeof(PacketType), packetType)) { throw new InvalidPacketTypeException("Invalid packet type"); } Type = (PacketType)Enum.ToObject(typeof(PacketType), packetType); if (!useUtf8) { Payload = reader.ReadAscii(); // Get payload length by subtracting 9 bytes (ID 4-Bytes, Type 4-Bytes, Null-terminator 1-Byte) if (Encoding.ASCII.GetByteCount(Payload) > Size - 9) { throw new LengthMismatchException("Payload length mismatch"); } } else { Payload = Encoding.UTF8.GetString(reader.ReadBytes(Size - 10)); reader.ReadByte(); } var nullTerminator = reader.ReadByte(); if (nullTerminator != 0x00) { throw new NullTerminatorMissingException("Missing last null-terminator"); } if (reader.BaseStream.Position != reader.BaseStream.Length) { throw new Exception("More data to read"); } } } }
public static Region[] GetRegions(this Stream s) { using (BinaryReader br = new BinaryReaderExt(s, Encoding.ASCII, true)) { s.Seek(0xF70, SeekOrigin.Begin); bool isDecrypting = br.ReadByte() != 0x44; // Begins with E or D s.Seek(0xF70 + 0xD, SeekOrigin.Begin); bool isBuildedISO = br.ReadByte() == 0x42; // End in BLD s.Seek(0xF70 + 0xF, SeekOrigin.Begin); bool isValidHash = isBuildedISO && br.ReadByte() != 0x44; // Ends in BLF /* Read the game Key */ s.Seek(0xF80, SeekOrigin.Begin); byte[] d1 = br.ReadBytes(0x10); byte[] d2 = br.ReadBytes(0x10); s.Seek(0, SeekOrigin.Begin); uint plainRegions = br.ReadUInt32().Swap(); Region[] regions = new Region[(plainRegions * 2) - 1]; s.Seek(4, SeekOrigin.Current); uint current = br.ReadUInt32().Swap(); bool isPlain = true; for (uint i = 0; i < regions.Length; i++) { uint next = br.ReadUInt32().Swap(); if (isPlain) { regions[i] = new PlainRegion(i, isDecrypting, isBuildedISO, isValidHash, current, next); } else { regions[i] = isDecrypting ? (Region) new CryptedRegion(i, d1, d2, current, next, false) : new DecryptedRegion(i, d1, d2, current, next, false); } isPlain = !isPlain; current = next; } s.Seek(0, SeekOrigin.Begin); return(regions); } }
/// <summary> /// /// </summary> /// <param name="path"></param> private void OpenSEMFile(string path) { using (BinaryReaderExt r = new BinaryReaderExt(new FileStream(path, FileMode.Open))) { r.BigEndian = true; r.Seek(8); var entryCount = r.ReadInt32(); var offsetTableStart = r.Position + (entryCount + 1) * 4; for (uint i = 0; i < entryCount; i++) { SEMEntry e = new SEMEntry(); e.Index = (int)i; Entries.Add(e); r.Seek(0x0C + i * 4); var startIndex = r.ReadInt32(); var endIndex = r.ReadInt32(); HashSet <int> UniqueEntries = new HashSet <int>(); int largestEntry = 0; for (uint j = 0; j < endIndex - startIndex; j++) { SEMSound s = new SEMSound(); s.Index = (int)j; r.Seek((uint)(offsetTableStart + startIndex * 4 + j * 4)); var dataOffsetStart = r.ReadUInt32(); var dataOffsetEnd = r.ReadUInt32(); if (dataOffsetEnd == 0) { dataOffsetEnd = (uint)r.Length; } r.Seek(dataOffsetStart); s.CommandData = r.ReadBytes((int)(dataOffsetEnd - dataOffsetStart)); e.Sounds.Add(s); var entryId = ((s.CommandData[1] & 0xFF) << 16) | ((s.CommandData[2] & 0xFF) << 8) | ((s.CommandData[3] & 0xFF)); if (!UniqueEntries.Contains(entryId)) { UniqueEntries.Add(entryId); } } e.UniqueCount = UniqueEntries.Count; //e.UniqueCount = largestEntry; } } }
/// <summary> /// Reads the texture from NTX /// </summary> /// <param name="reader">The reader.</param> public void Read(BinaryReaderExt reader) { TextureName = reader.ReadAsciiStatic(64); var textureSize = reader.ReadInt32(); #if DEBUG Unknown = reader.ReadInt32(); #else reader.ReadInt32(); #endif Texture = reader.ReadBytes(textureSize); }
private DSP ImportDSP(string filePath) { using (BinaryReaderExt r = new BinaryReaderExt(new FileStream(filePath, FileMode.Open))) { r.BigEndian = true; var dsp = new DSP(); r.ReadInt32(); var nibbleCount = r.ReadInt32(); dsp.Frequency = r.ReadInt32(); var channel = new DSPChannel(); channel.LoopFlag = r.ReadInt16(); channel.Format = r.ReadInt16(); var LoopStartOffset = r.ReadInt32(); var LoopEndOffset = r.ReadInt32(); var CurrentAddress = r.ReadInt32(); for (int k = 0; k < 0x10; k++) { channel.COEF[k] = r.ReadInt16(); } channel.Gain = r.ReadInt16(); channel.InitialPredictorScale = r.ReadInt16(); channel.InitialSampleHistory1 = r.ReadInt16(); channel.InitialSampleHistory2 = r.ReadInt16(); channel.LoopPredictorScale = r.ReadInt16(); channel.LoopSampleHistory1 = r.ReadInt16(); channel.LoopSampleHistory2 = r.ReadInt16(); r.ReadInt16(); // padding r.Seek(0x60); channel.NibbleCount = nibbleCount; channel.LoopStart = LoopStartOffset - CurrentAddress; channel.Data = r.ReadBytes((int)Math.Ceiling(nibbleCount / 2d)); dsp.Channels.Add(channel); r.BaseStream.Close(); return(dsp); } }
/// <summary> /// /// </summary> public void LoadFromStream(Stream s) { using (BinaryReaderExt r = new BinaryReaderExt(s)) { if (s.Length < 0x14) { return; } if (new string(r.ReadChars(4)) != "SPKG") { return; } GroupFlags = r.ReadUInt32(); Flags = r.ReadUInt32(); var ssmSize = r.ReadInt32(); ScriptBank = new SEMBank(); ScriptBank.Scripts = new SEMBankScript[r.ReadInt32()]; for (int i = 0; i < ScriptBank.Scripts.Length; i++) { ScriptBank.Scripts[i] = new SEMBankScript(); ScriptBank.Scripts[i].Decompile(r.GetSection(r.ReadUInt32(), r.ReadInt32())); } var name = r.ReadString(r.ReadByte()); if (ssmSize == 0) { SoundBank = null; } else { SoundBank = new SSM(); using (MemoryStream ssmStream = new MemoryStream(r.ReadBytes(ssmSize))) SoundBank.Open(name, ssmStream); } } }
private void FromDSP(byte[] data) { Channels.Clear(); using (BinaryReaderExt r = new BinaryReaderExt(new MemoryStream(data))) { r.BigEndian = true; r.ReadInt32(); var nibbleCount = r.ReadInt32(); Frequency = r.ReadInt32(); var channel = new DSPChannel(); channel.LoopFlag = r.ReadInt16(); channel.Format = r.ReadInt16(); var LoopStartOffset = r.ReadInt32(); var LoopEndOffset = r.ReadInt32(); var CurrentAddress = r.ReadInt32(); for (int k = 0; k < 0x10; k++) { channel.COEF[k] = r.ReadInt16(); } channel.Gain = r.ReadInt16(); channel.InitialPredictorScale = r.ReadInt16(); channel.InitialSampleHistory1 = r.ReadInt16(); channel.InitialSampleHistory2 = r.ReadInt16(); channel.LoopPredictorScale = r.ReadInt16(); channel.LoopSampleHistory1 = r.ReadInt16(); channel.LoopSampleHistory2 = r.ReadInt16(); r.ReadInt16(); // padding r.Seek(0x60); channel.NibbleCount = nibbleCount; channel.LoopStart = LoopStartOffset - CurrentAddress; channel.Data = r.ReadBytes((int)Math.Ceiling(nibbleCount / 2d)); Channels.Add(channel); r.BaseStream.Close(); } }
/// <summary> /// /// </summary> /// <param name="data"></param> /// <returns></returns> public static DSP ToDSP(byte[] data) { DSP dsp = new DSP(); dsp.Channels.Clear(); using (BinaryReaderExt r = new BinaryReaderExt(new MemoryStream(data))) { r.BigEndian = true; if (new string(r.ReadChars(7)) != " HALPST") { throw new NotSupportedException("Invalid HPS file"); } r.ReadByte(); dsp.Frequency = r.ReadInt32(); var channelCount = r.ReadInt32(); if (channelCount != 2) { throw new NotSupportedException("Only HPS with 2 channels are currently supported"); } for (int i = 0; i < channelCount; i++) { var channel = new DSPChannel(); channel.LoopFlag = r.ReadInt16(); channel.Format = r.ReadInt16(); var SA = r.ReadInt32(); var EA = r.ReadInt32(); var CA = r.ReadInt32(); for (int k = 0; k < 0x10; k++) { channel.COEF[k] = r.ReadInt16(); } channel.Gain = r.ReadInt16(); channel.InitialPredictorScale = r.ReadInt16(); channel.InitialSampleHistory1 = r.ReadInt16(); channel.InitialSampleHistory1 = r.ReadInt16(); channel.NibbleCount = EA - CA; channel.LoopStart = SA - CA; dsp.Channels.Add(channel); } // read blocks r.Position = 0x80; Dictionary <int, int> OffsetToLoopPosition = new Dictionary <int, int>(); List <byte> channelData1 = new List <byte>(); List <byte> channelData2 = new List <byte>(); while (true) { var pos = r.Position; var length = r.ReadInt32(); var lengthMinusOne = r.ReadInt32(); var next = r.ReadInt32(); { var initPS = r.ReadInt16(); var initsh1 = r.ReadInt16(); var initsh2 = r.ReadInt16(); var gain = r.ReadInt16(); } { var initPS = r.ReadInt16(); var initsh1 = r.ReadInt16(); var initsh2 = r.ReadInt16(); var gain = r.ReadInt16(); } var extra = r.ReadInt32(); OffsetToLoopPosition.Add((int)pos, channelData1.Count * 2); channelData1.AddRange(r.ReadBytes(length / 2)); channelData2.AddRange(r.ReadBytes(length / 2)); if (next < r.Position || next == -1) { if (next != -1) { foreach (var c in dsp.Channels) { c.LoopStart = OffsetToLoopPosition[next]; } } break; } else { r.Position = (uint)next; } } dsp.Channels[0].Data = channelData1.ToArray(); dsp.Channels[1].Data = channelData2.ToArray(); } return(dsp); }
/// <summary> /// /// </summary> /// <param name="filePath"></param> /// <returns></returns> public static List <SEMEntry> ReadSEMFile(string filePath, bool loadSoundBanks, MEX_Data mexData = null) { var Entries = new List <SEMEntry>(); Dictionary <int, SSM> indexToSSM = new Dictionary <int, SSM>(); if (loadSoundBanks) { foreach (var f in Directory.GetFiles(Path.GetDirectoryName(filePath))) { if (f.ToLower().EndsWith(".ssm")) { var ssm = new SSM(); ssm.Open(f); indexToSSM.Add(ssm.StartIndex, ssm); } } } //if (!loadSoundBanks) // return Entries; using (BinaryReaderExt r = new BinaryReaderExt(new FileStream(filePath, FileMode.Open))) { r.BigEndian = true; r.Seek(8); var entryCount = r.ReadInt32(); var offsetTableStart = r.Position + (entryCount + 1) * 4; for (uint i = 0; i < entryCount; i++) { SEMEntry e = new SEMEntry(); Entries.Add(e); r.Seek(0x0C + i * 4); var startIndex = r.ReadInt32(); var endIndex = r.ReadInt32(); var ssmStartIndex = int.MaxValue; for (uint j = 0; j < endIndex - startIndex; j++) { SEMScript s = new SEMScript(); r.Seek((uint)(offsetTableStart + startIndex * 4 + j * 4)); var dataOffsetStart = r.ReadUInt32(); var dataOffsetEnd = r.ReadUInt32(); if (dataOffsetEnd == 0) { dataOffsetEnd = (uint)r.Length; } r.Seek(dataOffsetStart); s.CommandData = r.ReadBytes((int)(dataOffsetEnd - dataOffsetStart)); e.AddScript(s); ssmStartIndex = Math.Min(ssmStartIndex, s.SoundCommandIndex); } if (loadSoundBanks && indexToSSM.ContainsKey(ssmStartIndex)) { e.SoundBank = indexToSSM[ssmStartIndex]; if (mexData != null) { var index = mexData.SSMTable.SSM_SSMFiles.Array.ToList().FindIndex(s => s.Value.Equals(e.SoundBank.Name)); if (index != -1) { e.SoundBank.GroupFlags = mexData.SSMTable.SSM_LookupTable[index].EntireFlag; e.SoundBank.Flag = mexData.SSMTable.SSM_BufferSizes[index].Flag; } } foreach (var v in e.Scripts) { v.SoundCommandIndex -= ssmStartIndex; } } } } return(Entries); }
public void UserAuthAnswerPacket() { var packet = new UserAuthAnswerPacket(); var bytes = packet.GetBytes(); using (var ms = new MemoryStream(bytes)) { using (var bs = new BinaryReaderExt(ms)) { var ticket = bs.ReadUInt32(); Assert.AreEqual(packet.Ticket, ticket); var result = bs.ReadInt32(); Assert.AreEqual(packet.Result, result); var time = bs.ReadInt32(); Assert.AreEqual(packet.Time, time); bs.ReadBytes(64); // Filler var serverListId = bs.ReadUInt16(); Assert.AreEqual(packet.ServerListId, serverListId); var serverCount = bs.ReadInt32(); Assert.AreEqual(packet.ServerCount, serverCount); // Normally we could read all servers, but for tests only the first // is interesting var serverName = bs.ReadUnicodeStatic(32); StringAssert.AreEqualIgnoringCase(serverName, packet.Servers[0].ServerName); var serverId = bs.ReadUInt32(); Assert.AreEqual(packet.Servers[0].ServerId, serverId); var playerCount = bs.ReadSingle(); Assert.AreEqual(packet.Servers[0].PlayerCount, playerCount); var maxPlayers = bs.ReadSingle(); Assert.AreEqual(packet.Servers[0].MaxPlayers, maxPlayers); var serverState = bs.ReadInt32(); Assert.AreEqual(packet.Servers[0].ServerState, serverState); var gameTime = bs.ReadInt32(); Assert.AreEqual(packet.Servers[0].GameTime, gameTime); var lobbyTime = bs.ReadInt32(); Assert.AreEqual(packet.Servers[0].LobbyTime, lobbyTime); var area1Time = bs.ReadInt32(); Assert.AreEqual(packet.Servers[0].Area1Time, area1Time); var area2Time = bs.ReadInt32(); Assert.AreEqual(packet.Servers[0].Area2Time, area2Time); var rankingUpdateTime = bs.ReadInt32(); Assert.AreEqual(packet.Servers[0].RankingUpdateTime, rankingUpdateTime); var gameServerIp = bs.ReadBytes(4); Assert.AreEqual(packet.Servers[0].GameServerIp, gameServerIp); var lobbyServerIp = bs.ReadBytes(4); Assert.AreEqual(packet.Servers[0].LobbyServerIp, lobbyServerIp); var areaServer1Ip = bs.ReadBytes(4); Assert.AreEqual(packet.Servers[0].AreaServer1Ip, areaServer1Ip); var areaServer2Ip = bs.ReadBytes(4); Assert.AreEqual(packet.Servers[0].AreaServer2Ip, areaServer2Ip); var rankingServerIp = bs.ReadBytes(4); Assert.AreEqual(packet.Servers[0].RankingServerIp, rankingServerIp); var gameServerPort = bs.ReadUInt16(); Assert.AreEqual(packet.Servers[0].GameServerPort, gameServerPort); var lobbyServerPort = bs.ReadUInt16(); Assert.AreEqual(packet.Servers[0].LobbyServerPort, lobbyServerPort); var areaServerPort = bs.ReadUInt16(); Assert.AreEqual(packet.Servers[0].AreaServerPort, areaServerPort); var areaServer2Port = bs.ReadUInt16(); Assert.AreEqual(packet.Servers[0].AreaServer2Port, areaServer2Port); var areaServerUdpPort = bs.ReadUInt16(); Assert.AreEqual(packet.Servers[0].AreaServerUdpPort, areaServerUdpPort); var areaServer2UdpPort = bs.ReadUInt16(); Assert.AreEqual(packet.Servers[0].AreaServer2UdpPort, areaServer2UdpPort); var rankingServerPort = bs.ReadUInt16(); Assert.AreEqual(packet.Servers[0].RankingServerPort, rankingServerPort); } } }
public static SBSurface Import(string FileName) { SBSurface surface = new SBSurface(); using (BinaryReaderExt reader = new BinaryReaderExt(new FileStream(FileName, FileMode.Open))) { DDS_Header header = new DDS_Header(); header.Read(reader); surface.Name = Path.GetFileNameWithoutExtension(FileName); surface.Width = header.dwWidth; surface.Height = header.dwHeight; if (header.dwFlags.HasFlag(DDSD.DEPTH)) { surface.Depth = header.dwDepth; } else { surface.Depth = 1; } if (header.ddspf.dwFourCC == 0x31545844) { surface.InternalFormat = InternalFormat.CompressedRgbaS3tcDxt1Ext; } else if (header.ddspf.dwFourCC == 0x30315844) { surface.InternalFormat = DXGItoInternal(header.DXT10Header.dxgiFormat); if (surface.InternalFormat == 0) { System.Windows.Forms.MessageBox.Show("DDS format not supported " + header.DXT10Header.dxgiFormat); return(null); } } else { if (((FourCC_DXGI)header.ddspf.dwFourCC) == FourCC_DXGI.D3DFMT_A32B32G32R32F) { surface.InternalFormat = InternalFormat.Rgba32f; surface.PixelFormat = PixelFormat.Rgba; surface.PixelType = PixelType.Float; } else { System.Windows.Forms.MessageBox.Show("DDS format not supported " + header.ddspf.dwFourCC.ToString("X")); return(null); } } // TODO: read other mips int w = surface.Width; int h = surface.Height; //SBConsole.WriteLine(header.dwCaps.ToString() + " " + header.dwCaps2.ToString() + " " + header.dwFlags.ToString()); for (int array = 0; array < (header.dwCaps2.HasFlag(DDSCAPS2.CUBEMAP_ALLFACES) ? 6 : 1); array++) { w = surface.Width; h = surface.Height; var mip = new MipArray(); for (int i = 0; i < (header.dwFlags.HasFlag(DDSD.MIPMAPCOUNT) ? header.dwMipMapCount : 1); i++) { var mipSize = Math.Max(1, ((w + 3) / 4)) * Math.Max(1, ((h + 3) / 4)) * (int)TextureFormatInfo.GetBPP(surface.InternalFormat); if (mipSize % TextureFormatInfo.GetBPP(surface.InternalFormat) != 0) { mipSize += (int)(TextureFormatInfo.GetBPP(surface.InternalFormat) - (mipSize % TextureFormatInfo.GetBPP(surface.InternalFormat))); } var data = reader.ReadBytes(mipSize); mip.Mipmaps.Add(data); w /= 2; h /= 2; } surface.Arrays.Add(mip); } if (reader.Position != reader.BaseStream.Length) { SBConsole.WriteLine("Warning: error reading dds " + reader.Position.ToString("X")); } } return(surface); }
public void Read(BinaryReaderExt r) { r.ReadByte(); MaterialData = r.ReadBytes(0xC); }
/// <summary> /// Used in Eighting Engine Games /// </summary> /// <param name="filePath"></param> private void OpenSDI(string filePath) { var sam = filePath.Replace(".sdi", ".sam"); if (!File.Exists(sam)) { return; } using (BinaryReaderExt r = new BinaryReaderExt(new FileStream(filePath, FileMode.Open))) using (BinaryReaderExt d = new BinaryReaderExt(new FileStream(sam, FileMode.Open))) { r.BigEndian = true; while (true) { var id = r.ReadInt32(); if (id == -1) { break; } var dataoffset = r.ReadUInt32(); var padding = r.ReadInt32(); var flags = r.ReadInt16(); var frequency = r.ReadInt16(); var value = r.ReadInt32(); r.Skip(8); // unknown uint coefOffset = r.ReadUInt32(); DSP dsp = new DSP(); dsp.Frequency = frequency; DSPChannel channel = new DSPChannel(); channel.NibbleCount = value; var temp = r.Position; var end = (uint)d.Length; if (r.ReadInt32() != -1) { end = r.ReadUInt32(); } r.Seek(coefOffset); r.ReadInt32(); r.ReadInt32(); for (int i = 0; i < 0x10; i++) { channel.COEF[i] = r.ReadInt16(); } r.Seek(temp); d.Seek(dataoffset); byte[] data = d.ReadBytes((int)(end - dataoffset)); channel.Data = data; channel.InitialPredictorScale = data[0]; dsp.Channels.Add(channel); Sounds.Add(dsp); } } }