public virtual void Read(BinaryReaderExt r) { EntryFlags = r.ReadInt64(); EntryNumber = r.ReadInt32(); bool hasString = r.ReadBoolean(); EntryName = r.ReadString(0x38); bool hasLabel = r.ReadBoolean(); EntryLabel = r.ReadString(0x40); bool hasStartPosition = r.ReadBoolean(); StartPosition = new LVDVector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); UseStartPosition = r.ReadBoolean(); // Unknown r.Skip(1); UnknownIndex2 = r.ReadInt32(); r.Skip(1); UnknownVector = new LVDVector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); UnknownIndex = r.ReadInt32(); r.Skip(1); BoneName = r.ReadString(0x40); }
public static HSD_Spline KMP_ExtractRouteSpline(string kmpFile) { List <HSD_Vector3> points = new List <HSD_Vector3>(); using (FileStream f = new FileStream(kmpFile, FileMode.Open)) using (BinaryReaderExt r = new BinaryReaderExt(f)) { r.BigEndian = true; r.Seek(0x14); var enpt = r.ReadUInt32(); r.Seek(enpt + 0x4C); r.Skip(4); int count = r.ReadInt16(); int unk = r.ReadInt16(); for (int i = 0; i < count; i++) { points.Add(new HSD_Vector3() { X = r.ReadSingle() * Scale, Y = r.ReadSingle() * Scale + YTrans, Z = r.ReadSingle() * Scale }); var range = r.ReadSingle(); r.Skip(4); // settings } } HSD_Spline spline = new HSD_Spline(); spline.Points = points.ToArray(); spline.PointCount = (short)points.Count; float totalLength = 0; foreach (var e in points) { totalLength += new Vector3(e.X, e.Y, e.Z).Length; } float[] lengths = new float[points.Count]; //float length = 0; for (int i = 0; i < lengths.Length; i++) { lengths[i] = i / (float)(lengths.Length - 1); //length += new Vector3(points[i].X, points[i].Y, points[i].Z).Length; } spline.TotalLength = totalLength; spline.Lengths = new HSDFloatArray() { Array = lengths }; return(spline); }
public override void Read(BinaryReaderExt r) { base.Read(r); r.Skip(1); ID = r.ReadInt32(); r.Skip(1); Type = r.ReadInt32(); X = r.ReadSingle(); Y = r.ReadSingle(); Z = r.ReadSingle(); r.Skip(0x10); }
public override void Read(BinaryReaderExt r) { base.Read(r); r.Skip(1); Type = (LVDDamageShapeType)r.ReadInt32(); if (!Enum.IsDefined(typeof(LVDDamageShapeType), Type)) { throw new NotImplementedException($"Unknown damage shape type {Type} at offset {r.BaseStream.Position - 4}"); } X = r.ReadSingle(); Y = r.ReadSingle(); Z = r.ReadSingle(); if (Type == LVDDamageShapeType.Sphere) { Radius = r.ReadSingle(); Dx = r.ReadSingle(); Dy = r.ReadSingle(); Dz = r.ReadSingle(); } if (Type == LVDDamageShapeType.Capsule) { Dx = r.ReadSingle(); Dy = r.ReadSingle(); Dz = r.ReadSingle(); Radius = r.ReadSingle(); } Unknown1 = r.ReadByte(); Unknown2 = r.ReadInt32(); }
public override void Read(BinaryReaderExt r) { base.Read(r); r.Skip(1); Left = r.ReadSingle(); Right = r.ReadSingle(); Top = r.ReadSingle(); Bottom = r.ReadSingle(); }
public override void Read(BinaryReaderExt r) { base.Read(r); r.Skip(1); ID = r.ReadInt32(); r.Skip(1); r.Skip(1); int sectionCount = r.ReadInt32(); for (int i = 0; i < sectionCount; i++) { r.Skip(1); var shape = new LVDShape(); shape.Read(r); Sections.Add(shape); } }
public override void Read(BinaryReaderExt r) { base.Read(r); r.Skip(1); Position.X = r.ReadSingle(); Position.Y = r.ReadSingle(); Angle = r.ReadSingle(); LineIndex = r.ReadInt32(); }
public override void Read(BinaryReaderExt r) { base.Read(r); r.Skip(1); ID = r.ReadInt32(); Shape = new LVDShape(); Shape.Read(r); }
public override void Read(BinaryReaderExt r) { base.Read(r); ID = r.ReadInt32(); r.Skip(1); Name = r.ReadString(0x40); X = r.ReadSingle(); Y = r.ReadSingle(); Z = r.ReadSingle(); W = r.ReadSingle(); Unknown1 = r.ReadInt32(); Unknown2 = r.ReadInt32(); }
public void Read(BinaryReaderExt r) { r.ReadByte(); Type = (LVDShapeType)r.ReadInt32(); X = r.ReadSingle(); Y = r.ReadSingle(); Z = r.ReadSingle(); W = r.ReadSingle(); r.ReadByte(); r.ReadByte(); int pointCount = r.ReadInt32(); for (int i = 0; i < pointCount; i++) { r.Skip(1); Points.Add(new LVDVector2(r.ReadSingle(), r.ReadSingle())); } }
private static void ParseDebugLine(BinaryReaderExt r) { // read header var debug_line_header = new ELF_Debug_Line() { length = r.ReadUInt32(), version = r.ReadUInt16(), header_length = r.ReadUInt32(), min_instruction_length = r.ReadByte(), default_is_stmt = r.ReadByte(), line_base = r.ReadSByte(), line_range = r.ReadByte(), opcode_base = r.ReadByte(), std_opcode_lengths = new byte[12] }; for (int k = 0; k < 12; k++) { debug_line_header.std_opcode_lengths[k] = r.ReadByte(); } // read directories while (r.PeekChar() != 0) { Debug.WriteLine(r.ReadString()); } r.Skip(1); // read files while (r.PeekChar() != 0) { Debug.WriteLine(r.ReadString() + " " + r.ReadByte() + " " + r.ReadByte() + " " + r.ReadByte()); } r.PrintPosition(); int address = 0; int op_index = 0; int file = 1; int line = 1; int column = 0; bool is_stmt = debug_line_header.default_is_stmt != 0; bool basic_block = false; bool end_sequence = false; bool prologue_end = false; bool epilogue_begin = false; int isa = 0; int dicriminator = 0; var op_code_start = r.Position; while (true) { var op = r.ReadByte(); switch (op) { case 0: // extended byte ReadLEB123(r); break; } } }
private static void ReadTrack(BinaryReaderExt r, int frameCount, int type, FOBJ_Player track, uint dataOffset, AnimNode node) { var offset = r.ReadUInt32() + dataOffset; var temp = r.Position; r.Seek(offset); int fCount = -1; float scale = 0; float[] frame = null, step = null, tan = null; if (type == 0x1) { fCount = r.ReadUInt16(); r.Skip(2); scale = r.ReadSingle(); float stepb = r.ReadSingle(); float base2 = r.ReadSingle(); frame = new float[fCount]; step = new float[fCount]; tan = new float[fCount]; for (int i = 0; i < fCount; i++) { var v = r.ReadInt32(); frame[i] = (v >> 24) & 0xFF; int th = v & 0xFFFFFF; step[i] = base2 + ((th >> 12) & 0xfff) * stepb; tan[i] = (Sign12Bit(th & 0xfff) / 32f); track.Keys.Add(new FOBJKey() { Frame = frame[i], Value = step[i], Tan = tan[i], InterpolationType = GXInterpolationType.HSD_A_OP_SPL }); } } if (type == 0x2) { fCount = r.ReadUInt16(); r.Skip(2); scale = r.ReadSingle(); float stepb = r.ReadSingle(); float base2 = r.ReadSingle(); frame = new float[fCount]; step = new float[fCount]; tan = new float[fCount]; for (int i = 0; i < fCount; i++) { frame[i] = r.ReadUInt16() / 32f; step[i] = base2 + r.ReadUInt16() * stepb; tan[i] = (r.ReadInt16() / 256f); track.Keys.Add(new FOBJKey() { Frame = frame[i], Value = step[i], Tan = tan[i], InterpolationType = GXInterpolationType.HSD_A_OP_SPL }); } } if (type == 0x3) { fCount = r.ReadUInt16(); r.Skip(2); scale = r.ReadSingle(); frame = new float[fCount]; step = new float[fCount]; tan = new float[fCount]; for (int i = 0; i < fCount; i++) { frame[i] = r.ReadSingle(); step[i] = r.ReadSingle(); tan[i] = r.ReadSingle(); track.Keys.Add(new FOBJKey() { Frame = frame[i], Value = step[i], Tan = tan[i], InterpolationType = GXInterpolationType.HSD_A_OP_SPL }); } } if (type == 0x4) { float stepb = r.ReadSingle(); float base2 = r.ReadSingle(); for (int i = 0; i < frameCount; i++) { float v = base2 + stepb * (r.ReadByte()); track.Keys.Add(new FOBJKey() { Frame = i, Value = v, InterpolationType = GXInterpolationType.HSD_A_OP_LIN }); } } if (type == 0x6) { for (int i = 0; i < frameCount; i++) { float v = r.ReadSingle(); track.Keys.Add(new FOBJKey() { Frame = i, Value = v, InterpolationType = GXInterpolationType.HSD_A_OP_LIN }); } } r.Seek(temp); }
/// <summary> /// /// </summary> /// <param name="filePath"></param> /// <returns></returns> public static JointAnimManager LoadCHR0(string filePath, Dictionary <int, string> BoneLabelMap) { JointAnimManager anim = new JointAnimManager(); Dictionary <string, int> nameToIndex = new Dictionary <string, int>(); foreach (var v in BoneLabelMap) { nameToIndex.Add(v.Value, v.Key); anim.Nodes.Add(new AnimNode()); } using (BinaryReaderExt r = new BinaryReaderExt(new FileStream(filePath, FileMode.Open))) { r.BigEndian = true; if (r.BaseStream.Length < 4 || new string(r.ReadChars(4)) != "CHR0") { throw new InvalidDataException("CHR0 file is not valid"); } r.Skip(4); int versionNum = r.ReadInt32(); if (versionNum != 4) { throw new InvalidDataException($"CHR0 version {versionNum} not supported"); } System.Console.WriteLine("Reading Track "); r.Seek(0x10); var indexGroupOffset = r.ReadUInt32(); var animName = r.ReadString(r.ReadInt32(), -1); r.Skip(4); anim.FrameCount = r.ReadUInt16(); int animDataCount = r.ReadUInt16(); r.Skip(8); r.Seek(indexGroupOffset); var sectionOffset = r.ReadUInt32() + indexGroupOffset; int sectionCount = r.ReadInt32(); for (uint i = 0; i < sectionCount; i++) { r.Seek(indexGroupOffset + 8 + 16 * i); r.Skip(4); // id and unknown r.Skip(2); // let r.Skip(2); // right var boneName = r.ReadString(r.ReadInt32() + (int)indexGroupOffset, -1); var dataOffset = r.ReadUInt32() + indexGroupOffset; if (dataOffset == indexGroupOffset) { sectionCount += 1; continue; } if (!nameToIndex.ContainsKey(boneName)) { continue; } r.Seek(dataOffset); var nameOff = r.Position + r.ReadUInt32(); var flags = r.ReadInt32(); int t_type = (flags >> 0x1e) & 0x3; int r_type = (flags >> 0x1b) & 0x7; int s_type = (flags >> 0x19) & 0x3; int hasT = (flags >> 0x18) & 0x1; int hasR = (flags >> 0x17) & 0x1; int hasS = (flags >> 0x16) & 0x1; int Zfixed = (flags >> 0x15) & 0x1; int Yfixed = (flags >> 0x14) & 0x1; int Xfixed = (flags >> 0x13) & 0x1; int RZfixed = (flags >> 0x12) & 0x1; int RYfixed = (flags >> 0x11) & 0x1; int RXfixed = (flags >> 0x10) & 0x1; int SZfixed = (flags >> 0xf) & 0x1; int SYfixed = (flags >> 0xe) & 0x1; int SXfixed = (flags >> 0xd) & 0x1; int Tiso = (flags >> 0x6) & 0x1; int Riso = (flags >> 0x5) & 0x1; int Siso = (flags >> 0x4) & 0x1; AnimNode node = new AnimNode(); FOBJ_Player trackX = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_TRAX }; FOBJ_Player trackY = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_TRAY }; FOBJ_Player trackZ = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_TRAZ }; FOBJ_Player trackRX = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_ROTX }; FOBJ_Player trackRY = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_ROTY }; FOBJ_Player trackRZ = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_ROTZ }; FOBJ_Player trackSX = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_SCAX }; FOBJ_Player trackSY = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_SCAY }; FOBJ_Player trackSZ = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_SCAZ }; if (hasS == 1) { ReadKeys(r, node, (int)anim.FrameCount, trackSX, trackSY, trackSZ, Siso == 1, SXfixed == 1, SYfixed == 1, SZfixed == 1, s_type, dataOffset); } if (hasR == 1) { ReadKeys(r, node, (int)anim.FrameCount, trackRX, trackRY, trackRZ, Riso == 1, RXfixed == 1, RYfixed == 1, RZfixed == 1, r_type, dataOffset); } if (hasT == 1) { ReadKeys(r, node, (int)anim.FrameCount, trackX, trackY, trackZ, Tiso == 1, Xfixed == 1, Yfixed == 1, Zfixed == 1, t_type, dataOffset); } if (trackX.Keys.Count > 1) { node.Tracks.Add(trackX); } if (trackY.Keys.Count > 1) { node.Tracks.Add(trackY); } if (trackZ.Keys.Count > 1) { node.Tracks.Add(trackZ); } if (trackRX.Keys.Count > 1) { node.Tracks.Add(trackRX); } if (trackRY.Keys.Count > 1) { node.Tracks.Add(trackRY); } if (trackRZ.Keys.Count > 1) { node.Tracks.Add(trackRZ); } if (trackSX.Keys.Count > 1) { node.Tracks.Add(trackSX); } if (trackSY.Keys.Count > 1) { node.Tracks.Add(trackSY); } if (trackSZ.Keys.Count > 1) { node.Tracks.Add(trackSZ); } foreach (var k in trackRX.Keys) { k.Value = MathHelper.DegreesToRadians(k.Value); k.Tan = MathHelper.DegreesToRadians(k.Value); } foreach (var k in trackRY.Keys) { k.Value = MathHelper.DegreesToRadians(k.Value); k.Tan = MathHelper.DegreesToRadians(k.Value); } foreach (var k in trackRZ.Keys) { k.Value = MathHelper.DegreesToRadians(k.Value); k.Tan = MathHelper.DegreesToRadians(k.Value); } Console.WriteLine(boneName + " Tracks:" + node.Tracks.Count); Console.WriteLine($"{trackX.Keys.Count} {trackY.Keys.Count} {trackZ.Keys.Count}"); Console.WriteLine($"{trackRX.Keys.Count} {trackRY.Keys.Count} {trackRZ.Keys.Count}"); Console.WriteLine($"{trackSX.Keys.Count} {trackSY.Keys.Count} {trackSZ.Keys.Count}"); anim.Nodes[nameToIndex[boneName]] = node; } } return(anim); }
/// <summary> /// /// </summary> /// <param name="filePath"></param> /// <returns></returns> public static JointAnimManager LoadCHR0(string filePath, JointMap jointMap) { JointAnimManager anim = new JointAnimManager(); for (int i = 0; i < jointMap.Count; i++) { anim.Nodes.Add(new AnimNode()); } using (BinaryReaderExt r = new BinaryReaderExt(new FileStream(filePath, FileMode.Open))) { r.BigEndian = true; if (r.BaseStream.Length < 4 || new string(r.ReadChars(4)) != "CHR0") { throw new InvalidDataException("CHR0 file is not valid"); } r.Skip(4); int versionNum = r.ReadInt32(); if (versionNum != 4) { throw new InvalidDataException($"CHR0 version {versionNum} not supported"); } r.Seek(0x10); var indexGroupOffset = r.ReadUInt32(); var animName = r.ReadString(r.ReadInt32(), -1); r.Skip(4); anim.FrameCount = r.ReadUInt16() - 1; int animDataCount = r.ReadUInt16(); r.Skip(8); r.Seek(indexGroupOffset); var sectionOffset = r.ReadUInt32() + indexGroupOffset; int sectionCount = r.ReadInt32(); for (uint i = 0; i < sectionCount; i++) { r.Seek(indexGroupOffset + 8 + 16 * i); r.Skip(4); // id and unknown r.Skip(2); // let r.Skip(2); // right var boneName = r.ReadString(r.ReadInt32() + (int)indexGroupOffset, -1); var dataOffset = r.ReadUInt32() + indexGroupOffset; if (dataOffset == indexGroupOffset) { sectionCount += 1; continue; } if (jointMap.IndexOf(boneName) == -1) { continue; } r.Seek(dataOffset); var nameOff = r.Position + r.ReadUInt32(); var flags = r.ReadInt32(); //Console.WriteLine(boneName + " " + flags.ToString("X")); //r.PrintPosition(); //01BFE019 int t_type = (flags >> 0x1e) & 0x3; int r_type = (flags >> 0x1b) & 0x7; int s_type = (flags >> 0x19) & 0x3; int hasT = (flags >> 0x18) & 0x1; int hasR = (flags >> 0x17) & 0x1; int hasS = (flags >> 0x16) & 0x1; int Zfixed = (flags >> 0x15) & 0x1; int Yfixed = (flags >> 0x14) & 0x1; int Xfixed = (flags >> 0x13) & 0x1; int RZfixed = (flags >> 0x12) & 0x1; int RYfixed = (flags >> 0x11) & 0x1; int RXfixed = (flags >> 0x10) & 0x1; int SZfixed = (flags >> 0xf) & 0x1; int SYfixed = (flags >> 0xe) & 0x1; int SXfixed = (flags >> 0xd) & 0x1; int Tiso = (flags >> 0x6) & 0x1; int Riso = (flags >> 0x5) & 0x1; int Siso = (flags >> 0x4) & 0x1; AnimNode node = new AnimNode(); FOBJ_Player trackX = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_TRAX }; FOBJ_Player trackY = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_TRAY }; FOBJ_Player trackZ = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_TRAZ }; FOBJ_Player trackRX = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_ROTX }; FOBJ_Player trackRY = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_ROTY }; FOBJ_Player trackRZ = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_ROTZ }; FOBJ_Player trackSX = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_SCAX }; FOBJ_Player trackSY = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_SCAY }; FOBJ_Player trackSZ = new FOBJ_Player() { JointTrackType = JointTrackType.HSD_A_J_SCAZ }; if (hasS == 1) { ReadKeys(r, node, (int)anim.FrameCount, trackSX, trackSY, trackSZ, Siso == 1, SXfixed == 1, SYfixed == 1, SZfixed == 1, s_type, dataOffset); } if (hasR == 1) { ReadKeys(r, node, (int)anim.FrameCount, trackRX, trackRY, trackRZ, Riso == 1, RXfixed == 1, RYfixed == 1, RZfixed == 1, r_type, dataOffset); } if (hasT == 1) { ReadKeys(r, node, (int)anim.FrameCount, trackX, trackY, trackZ, Tiso == 1, Xfixed == 1, Yfixed == 1, Zfixed == 1, t_type, dataOffset); } if (trackX.Keys.Count > 0) { node.Tracks.Add(trackX); } if (trackY.Keys.Count > 0) { node.Tracks.Add(trackY); } if (trackZ.Keys.Count > 0) { node.Tracks.Add(trackZ); } if (trackRX.Keys.Count > 0) { node.Tracks.Add(trackRX); } if (trackRY.Keys.Count > 0) { node.Tracks.Add(trackRY); } if (trackRZ.Keys.Count > 0) { node.Tracks.Add(trackRZ); } if (trackSX.Keys.Count > 0) { node.Tracks.Add(trackSX); } if (trackSY.Keys.Count > 0) { node.Tracks.Add(trackSY); } if (trackSZ.Keys.Count > 0) { node.Tracks.Add(trackSZ); } foreach (var k in trackRX.Keys) { k.Value = MathHelper.DegreesToRadians(k.Value); k.Tan = MathHelper.DegreesToRadians(k.Tan); } foreach (var k in trackRY.Keys) { k.Value = MathHelper.DegreesToRadians(k.Value); k.Tan = MathHelper.DegreesToRadians(k.Tan); } foreach (var k in trackRZ.Keys) { k.Value = MathHelper.DegreesToRadians(k.Value); k.Tan = MathHelper.DegreesToRadians(k.Tan); } // make sure all tracks start at frame 0 foreach (var track in node.Tracks) { if (track.Keys.Count > 0 && track.Keys[0].Frame != 0) { track.Keys.Insert(0, new FOBJKey() { Frame = 0, Value = track.Keys[0].Value, InterpolationType = GXInterpolationType.HSD_A_OP_CON, }); } } //Console.WriteLine(boneName + " Tracks:" + node.Tracks.Count + " " + flags.ToString("X")); //Console.WriteLine($"{trackX.Keys.Count} {trackY.Keys.Count} {trackZ.Keys.Count}"); //Console.WriteLine($"{trackRX.Keys.Count} {trackRY.Keys.Count} {trackRZ.Keys.Count}"); //Console.WriteLine($"{trackSX.Keys.Count} {trackSY.Keys.Count} {trackSZ.Keys.Count}"); anim.Nodes[jointMap.IndexOf(boneName)] = node; } } return(anim); }
/// <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); } } }
private static void FromBRSTM(this DSP dsp, string filePath) { using (FileStream s = new FileStream(filePath, FileMode.Open)) using (BinaryReaderExt r = new BinaryReaderExt(s)) { if (new string(r.ReadChars(4)) != "RSTM") { throw new NotSupportedException("File is not a valid BRSTM file"); } r.BigEndian = true; r.BigEndian = r.ReadUInt16() == 0xFEFF; r.Skip(2); // 01 00 version r.Skip(4); // filesize r.Skip(2); // 00 40 - header length r.Skip(2); // 00 02 - header version var headOffset = r.ReadUInt32(); var headSize = r.ReadUInt32(); var adpcOffset = r.ReadUInt32(); var adpcSize = r.ReadUInt32(); var dataOffset = r.ReadUInt32(); var dataSize = r.ReadUInt32(); // can skip adpc section when reading because it just contains sample history // parse head section // -------------------------------------------------------------- r.Position = headOffset; if (new string(r.ReadChars(4)) != "HEAD") { throw new NotSupportedException("BRSTM does not have a valid HEAD"); } r.Skip(4); // section size r.Skip(4); // 01 00 00 00 marker var chunk1Offset = r.ReadUInt32() + 8 + headOffset; r.Skip(4); // 01 00 00 00 marker var chunk2Offset = r.ReadUInt32() + 8 + headOffset; r.Skip(4); // 01 00 00 00 marker var chunk3Offset = r.ReadUInt32() + 8 + headOffset; // -------------------------------------------------------------- r.Seek(chunk1Offset); var codec = (BRSTM_CODEC)r.ReadByte(); var loopFlag = r.ReadByte(); var channelCount = r.ReadByte(); r.Skip(1); // padding if (codec != BRSTM_CODEC.ADPCM_4bit) { throw new NotSupportedException("only 4bit ADPCM files currently supported"); } var sampleRate = r.ReadUInt16(); r.Skip(2); // padding dsp.Frequency = sampleRate; var loopStart = r.ReadUInt32(); var totalSamples = r.ReadUInt32(); var dataPointer = r.ReadUInt32(); // DATA offset int blockCount = r.ReadInt32(); var blockSize = r.ReadUInt32(); var samplesPerBlock = r.ReadInt32(); var sizeOfFinalBlock = r.ReadUInt32(); var samplesInFinalBlock = r.ReadInt32(); var sizeOfFinalBlockWithPadding = r.ReadUInt32(); var samplesPerEntry = r.ReadInt32(); var bytesPerEntry = r.ReadInt32(); // -------------------------------------------------------------- r.Seek(chunk2Offset); var numOfTracks = r.ReadByte(); var trackDescType = r.ReadByte(); r.Skip(2); // padding for (uint i = 0; i < numOfTracks; i++) { r.Seek(chunk1Offset + 4 + 8 * i); r.Skip(1); // 01 padding var descType = r.ReadByte(); r.Skip(2); // padding var descOffset = r.ReadUInt32() + 8 + headOffset; r.Seek(descOffset); switch (descType) { case 0: { int channelsInTrack = r.ReadByte(); int leftChannelID = r.ReadByte(); int rightChannelID = r.ReadByte(); r.Skip(1); // padding } break; case 1: { var volume = r.ReadByte(); var panning = r.ReadByte(); r.Skip(2); // padding r.Skip(4); // padding int channelsInTrack = r.ReadByte(); int leftChannelID = r.ReadByte(); int rightChannelID = r.ReadByte(); r.Skip(1); // 01 padding } break; } } // -------------------------------------------------------------- r.Seek(chunk3Offset); var channelCountAgain = r.ReadByte(); r.Skip(3); for (uint i = 0; i < channelCountAgain; i++) { r.Seek(chunk3Offset + 4 + 8 * i); r.Skip(4); // 01000000 marker var offset = r.ReadUInt32() + headOffset + 8; r.Seek(offset); // channel information var channel = new DSPChannel(); dsp.Channels.Add(channel); channel.LoopFlag = loopFlag; channel.LoopStart = (int)loopStart; r.Skip(4); // 01000000 marker r.Skip(4); // offset to coefficients (they follow directly after) 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.Skip(2); // padding // get channel data using (MemoryStream channelStream = new MemoryStream()) { for (uint j = 0; j < blockCount; j++) { var bs = blockSize; var actualBlockSize = blockSize; if (j == blockCount - 1) { bs = sizeOfFinalBlockWithPadding; actualBlockSize = sizeOfFinalBlock; } channelStream.Write(r.GetSection(dataPointer + j * (blockSize * channelCountAgain) + bs * i, (int)actualBlockSize), 0, (int)actualBlockSize); } channel.Data = channelStream.ToArray(); channel.NibbleCount = channel.Data.Length * 2; } } dsp.LoopPoint = TimeSpan.FromMilliseconds(loopStart / (double)sampleRate * 1000).ToString(); } }
/// <summary> /// /// </summary> /// <param name="output"></param> /// <param name="name"></param> /// <param name="datas"></param> /// <param name="structToFunctionName"></param> private void DecompileGroup(StringBuilder output, string name, HSDStruct datas) { if (structToFunctionName.ContainsKey(datas)) { return; } structToFunctionName.Add(datas, name); output.AppendLine(name); output.AppendLine("{"); using (BinaryReaderExt r = new BinaryReaderExt(new MemoryStream(datas.GetData()))) { byte flag = (byte)(r.ReadByte() >> 2); var cmd = ActionCommon.GetMeleeCMDAction(flag); while (flag != 0) { r.BaseStream.Position -= 1; var size = cmd.ByteSize; var command = r.GetSection(r.Position, size); r.Skip((uint)size); if (flag == 5 || flag == 7) //goto { var re = datas.GetReference <HSDAccessor>((int)r.BaseStream.Position - 4); if (re != null) { if (!tempStructToName.ContainsKey(re._s)) { if (structToFunctionName.ContainsKey(re._s)) { tempStructToName.Add(re._s, structToFunctionName[re._s]); } else { tempStructToName.Add(re._s, name + "_" + ((int)r.BaseStream.Position - 4).ToString("X4")); } } var funcname = tempStructToName[re._s]; output.AppendLine("\t" + (flag == 5 ? "Goto" : "Subroutine") + "(" + funcname + ");"); } } else { output.AppendLine("\t" + DecompileCommand(command)); } if (r.BaseStream.Position >= r.BaseStream.Length) { break; } flag = (byte)(r.ReadByte() >> 2); cmd = ActionCommon.GetMeleeCMDAction(flag); } } output.AppendLine("}"); foreach (var re in datas.References) { DecompileGroup(output, name + "_" + re.Key.ToString("X4"), re.Value); } }
public override void Read(BinaryReaderExt r) { base.Read(r); r.Skip(0x2); //x01 01 int spawnCount = r.ReadInt32(); for (int i = 0; i < spawnCount; i++) { r.Skip(1); var shape = new LVDShape(); shape.Read(r); Spawns.Add(shape); } r.Skip(0x2); //x01 01 int zoneCount = r.ReadInt32(); for (int i = 0; i < zoneCount; i++) { r.Skip(1); var shape = new LVDShape(); shape.Read(r); Zones.Add(shape); } r.Skip(0x2); //x01 01 Unknown1 = r.ReadInt32(); //Only seen as 0 r.Skip(1); //x01 ID = r.ReadInt32(); r.Skip(1); //x01 int spawnIdCount = r.ReadInt32(); for (int i = 0; i < spawnIdCount; i++) { r.Skip(1); SpawnIDs.Add(r.ReadInt32()); } r.Skip(1); //x01 Unknown2 = r.ReadInt32(); //Only seen as 0 r.Skip(1); //x01 int zoneIdCount = r.ReadInt32(); for (int i = 0; i < zoneIdCount; i++) { r.Skip(1); ZoneIDs.Add(r.ReadInt32()); } }