Exemple #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static short[] GetJointTable(string filePath)
        {
            if (!File.Exists(filePath))
            {
                MessageBox.Show("No JCV file loaded", "JCV File", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return(new short[0]);
            }

            using (BinaryReaderExt r = new BinaryReaderExt(new FileStream(filePath, FileMode.Open)))
            {
                r.BigEndian = true;

                r.Seek(0x10);
                var count = r.ReadInt16();

                short[] vals = new short[count];

                for (int i = 0; i < vals.Length; i++)
                {
                    vals[i] = r.ReadInt16();
                }

                return(vals);
            }
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        public bool Read(BinaryReaderExt Reader, GX_Attribute[] Attributes)
        {
            PrimitiveType = (GXPrimitiveType)Reader.ReadByte();

            if (PrimitiveType == 0)
            {
                return(false);
            }

            var count = Reader.ReadInt16();

            Indices = new GX_IndexGroup[count];
            for (int j = 0; j < count; j++)
            {
                GX_IndexGroup g = new GX_IndexGroup();
                g.Indices = new ushort[Attributes.Length];
                int i = 0;
                Indices[j] = g;
                foreach (var att in Attributes)
                {
                    if (att.AttributeName == GXAttribName.GX_VA_NULL)
                    {
                        continue;
                    }
                    switch (att.AttributeType)
                    {
                    case GXAttribType.GX_DIRECT:
                        if (att.AttributeName == GXAttribName.GX_VA_CLR0)
                        {
                            g.Clr0 = ReadDirectGXColor(Reader, (int)att.CompType);
                        }
                        else if (att.AttributeName == GXAttribName.GX_VA_CLR1)
                        {
                            g.Clr1 = ReadDirectGXColor(Reader, (int)att.CompType);
                        }
                        else
                        {
                            g.Indices[i] = Reader.ReadByte();
                        }
                        break;

                    case GXAttribType.GX_INDEX8:
                        g.Indices[i] = Reader.ReadByte();
                        break;

                    case GXAttribType.GX_INDEX16:
                        g.Indices[i] = Reader.ReadUInt16();
                        break;
                    }
                    i++;
                }
            }
            return(true);
        }
Exemple #4
0
        private static double ParseFloat(BinaryReaderExt d, GXAnimDataFormat Format, float Scale)
        {
            d.BigEndian = false;
            switch (Format)
            {
            case GXAnimDataFormat.HSD_A_FRAC_FLOAT:
                return(d.ReadSingle());

            case GXAnimDataFormat.HSD_A_FRAC_S16:
                return(d.ReadInt16() / (double)Scale);

            case GXAnimDataFormat.HSD_A_FRAC_U16:
                return(d.ReadUInt16() / (double)Scale);

            case GXAnimDataFormat.HSD_A_FRAC_S8:
                return(d.ReadSByte() / (double)Scale);

            case GXAnimDataFormat.HSD_A_FRAC_U8:
                return(d.ReadByte() / (double)Scale);

            default:
                return(0);
            }
        }
Exemple #5
0
        /// <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);
        }
Exemple #6
0
        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();
            }
        }
Exemple #7
0
            /// <summary>
            ///
            /// </summary>
            /// <returns></returns>
            public object[] Decode(byte code, BinaryReaderExt r)
            {
                var output = new List <object>(Parameters.Length);

                for (int i = 0; i < Parameters.Length; i++)
                {
                    var k = Parameters[i];

                    switch (k)
                    {
                    case 'e':
                        // extended byte
                        int e = r.ReadByte();

                        if ((e & 0x80) > 0)
                        {
                            e = ((e & 0x7F) << 8 | r.ReadByte());
                        }

                        output.Add((short)e);
                        break;

                    case 'b':
                        output.Add(r.ReadByte());
                        break;

                    case 'f':
                        output.Add(r.ReadSingle());
                        break;

                    case 's':
                        output.Add(r.ReadInt16());
                        break;

                    case 'c':
                    {
                        // custom parameters
                        //var behavior = code >> 4;
                        var param_count = code & 0xF;

                        for (int j = 0; j < 4; j++)
                        {
                            if (((param_count >> i) & 1) == 1)
                            {
                                output.Add(r.ReadByte());
                            }
                        }
                    }
                    break;

                    case 'p':
                    case 'v':
                    {
                        if ((code & 0x01) != 0)
                        {
                            output.Add(r.ReadSingle());
                        }
                        else
                        {
                            output.Add(0);
                        }

                        if ((code & 0x02) != 0)
                        {
                            output.Add(r.ReadSingle());
                        }
                        else
                        {
                            output.Add(0);
                        }

                        if ((code & 0x04) != 0)
                        {
                            output.Add(r.ReadSingle());
                        }
                        else
                        {
                            output.Add(0);
                        }
                    }
                    break;

                    case 'r':
                    {
                        var behavior = r.ReadByte();

                        output.Add((behavior & 0x10) != 0);
                        output.Add((behavior & 0x20) != 0);

                        output.Add(r.ReadByte());

                        if ((behavior & 0x01) != 0)
                        {
                            output.Add(r.ReadByte());
                        }
                        else
                        {
                            output.Add(0);
                        }

                        if ((behavior & 0x02) != 0)
                        {
                            output.Add(r.ReadByte());
                        }
                        else
                        {
                            output.Add(0);
                        }

                        if ((behavior & 0x04) != 0)
                        {
                            output.Add(r.ReadByte());
                        }
                        else
                        {
                            output.Add(0);
                        }

                        if ((behavior & 0x08) != 0)
                        {
                            output.Add(r.ReadByte());
                        }
                        else
                        {
                            output.Add(0);
                        }
                    }
                    break;

                    case 'm':
                    {
                        var behavior = r.ReadByte();

                        if ((behavior & 0x01) != 0)
                        {
                            output.Add(r.ReadByte());
                        }
                        else
                        {
                            output.Add(0);
                        }

                        if ((behavior & 0x08) != 0)
                        {
                            output.Add(r.ReadByte());
                        }
                        else
                        {
                            output.Add(0);
                        }
                    }
                    break;
                    }
                }

                return(output.ToArray());
            }
Exemple #8
0
        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);
        }
Exemple #9
0
        public static KAR_grCollisionNode KCLtoKAR(string kclFile, out KAR_grCollisionTree tree)
        {
            KAR_grCollisionNode node = new KAR_grCollisionNode();

            List <KAR_CollisionTriangle> tris  = new List <KAR_CollisionTriangle>();
            List <GXVector3>             verts = new List <GXVector3>();

            using (FileStream f = new FileStream(kclFile, FileMode.Open))
                using (BinaryReaderExt r = new BinaryReaderExt(f))
                {
                    r.BigEndian = true;

                    var posOffset  = r.ReadInt32();
                    var nrmOffset  = r.ReadInt32();
                    var triOffset  = r.ReadInt32() + 0x10;
                    var partOffste = r.ReadInt32();

                    var triCount = (partOffste - triOffset) / 0x10;
                    for (int i = 0; i < triCount; i++)
                    {
                        r.Seek((uint)(triOffset + i * 0x10));

                        var length = r.ReadSingle();
                        var pi     = r.ReadInt16();
                        var di     = r.ReadInt16();
                        var n1     = r.ReadInt16();
                        var n2     = r.ReadInt16();
                        var n3     = r.ReadInt16();
                        var fl     = r.ReadInt16();

                        r.Seek((uint)(posOffset + pi * 0xC));
                        var position = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());

                        r.Seek((uint)(nrmOffset + di * 0xC));
                        var direction = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());

                        r.Seek((uint)(nrmOffset + n1 * 0xC));
                        var normalA = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());

                        r.Seek((uint)(nrmOffset + n2 * 0xC));
                        var normalB = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());

                        r.Seek((uint)(nrmOffset + n3 * 0xC));
                        var normalC = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());

                        var crossA  = Vector3.Cross(normalA, direction);
                        var crossB  = Vector3.Cross(normalB, direction);
                        var vertex1 = position;
                        var vertex2 = position + crossB * (length / Vector3.Dot(crossB, normalC));
                        var vertex3 = position + crossA * (length / Vector3.Dot(crossA, normalC));

                        tris.Add(new KAR_CollisionTriangle()
                        {
                            Flags = 0x81,
                            V1    = verts.Count + 2,
                            V2    = verts.Count + 1,
                            V3    = verts.Count
                        });

                        // scale
                        vertex1 *= Scale;
                        vertex2 *= Scale;
                        vertex3 *= Scale;

                        vertex1.Y += YTrans;
                        vertex2.Y += YTrans;
                        vertex3.Y += YTrans;

                        verts.Add(new GXVector3()
                        {
                            X = vertex1.X, Y = vertex1.Y, Z = vertex1.Z
                        });
                        verts.Add(new GXVector3()
                        {
                            X = vertex2.X, Y = vertex2.Y, Z = vertex2.Z
                        });
                        verts.Add(new GXVector3()
                        {
                            X = vertex3.X, Y = vertex3.Y, Z = vertex3.Z
                        });
                    }
                }

            {
                var height = verts.Min(e => e.Y) - 10;

                var v1 = new Vector3(-10000, height, -10000);
                var v2 = new Vector3(10000, height, -10000);
                var v3 = new Vector3(10000, height, 10000);
                var v4 = new Vector3(-10000, height, 10000);

                tris.Add(new KAR_CollisionTriangle()
                {
                    Flags = 0x81,
                    V1    = verts.Count,
                    V2    = verts.Count + 1,
                    V3    = verts.Count + 2
                });

                verts.Add(new GXVector3()
                {
                    X = v1.X, Y = v1.Y, Z = v1.Z
                });
                verts.Add(new GXVector3()
                {
                    X = v2.X, Y = v2.Y, Z = v2.Z
                });
                verts.Add(new GXVector3()
                {
                    X = v3.X, Y = v3.Y, Z = v3.Z
                });

                tris.Add(new KAR_CollisionTriangle()
                {
                    Flags = 0x81,
                    V1    = verts.Count,
                    V2    = verts.Count + 1,
                    V3    = verts.Count + 2
                });

                verts.Add(new GXVector3()
                {
                    X = v1.X, Y = v1.Y, Z = v1.Z
                });
                verts.Add(new GXVector3()
                {
                    X = v3.X, Y = v3.Y, Z = v3.Z
                });
                verts.Add(new GXVector3()
                {
                    X = v4.X, Y = v4.Y, Z = v4.Z
                });
            }

            node.Triangles = tris.ToArray();
            node.Vertices  = verts.ToArray();
            node.Joints    = new KAR_CollisionJoint[]
            {
                new KAR_CollisionJoint()
                {
                    VertexStart = 0,
                    VertexSize  = verts.Count,
                    FaceStart   = 0,
                    FaceSize    = tris.Count
                }
            };

            tree = BucketGen.GenerateBucketPartition(node);

            return(node);
        }
Exemple #10
0
        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();
                }
        }
Exemple #11
0
            public void Parse(BinaryReaderExt r)
            {
                r.BigEndian = true;

                var start = r.Position;

                var sectionCount        = r.ReadInt32();
                var sectionHeaderLength = r.ReadInt32();

                PlaySpeed = r.ReadSingle();
                EndTime   = r.ReadSingle();

                for (int j = 0; j < sectionCount; j++)
                {
                    Joint joint = new Joint();

                    Joints.Add(joint);

                    joint.Flag1  = r.ReadByte();
                    joint.Flag2  = r.ReadByte();
                    joint.Flag3  = r.ReadUInt16();
                    joint.BoneID = r.ReadInt16();
                    var floatCount = r.ReadInt16();

                    joint.MaxTime = r.ReadSingle();
                    joint.Unknown = r.ReadInt32();

                    var offset1 = r.ReadUInt32() + start;
                    var offset2 = r.ReadUInt32() + start;
                    var offset3 = r.ReadUInt32() + start;
                    var offset4 = r.ReadUInt32() + start;

                    if (offset3 != start)
                    {
                        throw new NotSupportedException("Section 3 detected");
                    }

                    if (offset4 != start)
                    {
                        throw new NotSupportedException("Section 4 detected");
                    }

                    var temp = r.Position;
                    for (uint k = 0; k < floatCount; k++)
                    {
                        Key key = new Key();

                        r.Seek(offset1 + 4 * k);
                        key.Time = r.ReadSingle();

                        if (offset2 != start)
                        {
                            r.Seek(offset2 + 8 * k);

                            key.X = BitConverter.ToSingle(BitConverter.GetBytes(((r.ReadByte() & 0xFF) << 24) | ((r.ReadByte() & 0xFF) << 16)), 0);
                            key.Y = BitConverter.ToSingle(BitConverter.GetBytes(((r.ReadByte() & 0xFF) << 24) | ((r.ReadByte() & 0xFF) << 16)), 0);
                            key.Z = BitConverter.ToSingle(BitConverter.GetBytes(((r.ReadByte() & 0xFF) << 24) | ((r.ReadByte() & 0xFF) << 16)), 0);
                            key.W = BitConverter.ToSingle(BitConverter.GetBytes(((r.ReadByte() & 0xFF) << 24) | ((r.ReadByte() & 0xFF) << 16)), 0);
                        }

                        joint.Keys.Add(key);
                    }


                    r.Seek(temp);
                }
            }
Exemple #12
0
        /// <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);
                    }
                }
        }
Exemple #13
0
        /// <summary>
        /// Melee's sound format
        /// </summary>
        /// <param name="filePath"></param>
        private void OpenSSM(string filePath)
        {
            using (BinaryReaderExt r = new BinaryReaderExt(new FileStream(filePath, FileMode.Open)))
            {
                r.BigEndian = true;

                var headerLength = r.ReadInt32() + 0x10;
                var dataOff      = r.ReadInt32();
                var soundCount   = r.ReadInt32();
                Unknown = r.ReadInt32();

                for (int i = 0; i < soundCount; i++)
                {
                    var sound = new DSP();
                    sound.Index = i;
                    var ChannelCount = r.ReadInt32();
                    sound.Frequency = r.ReadInt32();

                    sound.Channels.Clear();
                    for (int j = 0; j < ChannelCount; j++)
                    {
                        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

                        channel.NibbleCount = LoopEndOffset - CurrentAddress;
                        channel.LoopStart   = LoopStartOffset - CurrentAddress;

                        sound.Channels.Add(channel);

                        var DataOffset = headerLength + (int)Math.Ceiling(CurrentAddress / 2d) - 1;

                        channel.Data = r.GetSection((uint)DataOffset, (int)Math.Ceiling(channel.NibbleCount / 2d) + 1);
                    }

                    Sounds.Add(sound);
                }
            }
        }
Exemple #14
0
        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);
            }
        }
Exemple #15
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filePath"></param>
        public void Open(string name, Stream s)
        {
            Name = name;
            using (BinaryReaderExt r = new BinaryReaderExt(s))
            {
                r.BigEndian = true;

                var headerLength = r.ReadInt32() + 0x10;
                var dataOff      = r.ReadInt32();
                var soundCount   = r.ReadInt32();
                StartIndex = r.ReadInt32();

                Sounds = new DSP[soundCount];

                for (int i = 0; i < soundCount; i++)
                {
                    var sound        = new DSP();
                    var ChannelCount = r.ReadInt32();
                    sound.Frequency = r.ReadInt32();

                    sound.Channels.Clear();
                    for (int j = 0; j < ChannelCount; j++)
                    {
                        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

                        channel.NibbleCount = LoopEndOffset - CurrentAddress;
                        channel.LoopStart   = LoopStartOffset - CurrentAddress;

                        sound.Channels.Add(channel);

                        var DataOffset = headerLength + (int)Math.Ceiling(CurrentAddress / 2d) - 1;

                        channel.Data = r.GetSection((uint)DataOffset, (int)Math.Ceiling(channel.NibbleCount / 2d) + 1);
                    }

                    Sounds[i] = sound;
                }
            }
        }
Exemple #16
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="elfFile"></param>
        public RelocELF(byte[] elfFile)
        {
            using (MemoryStream mstream = new MemoryStream(elfFile))
                using (BinaryReaderExt r = new BinaryReaderExt(mstream))
                {
                    // Parse Header

                    if (!(r.ReadByte() == 0x7F && r.ReadByte() == 0x45 && r.ReadByte() == 0x4C && r.ReadByte() == 0x46))
                    {
                        throw new InvalidDataException("Not a valid ELF file");
                    }

                    byte bitType = r.ReadByte(); // 1 - 32, 2 - 64
                    if (bitType != 1)
                    {
                        throw new NotSupportedException("Only 32 bit ELF files are currently supported");
                    }

                    r.BigEndian = r.ReadByte() == 2;

                    // I only care about the sections
                    r.Seek(0x20);
                    var sectionOffset = r.ReadUInt32();
                    r.Seek(0x2E);
                    var sectionHeaderSize  = r.ReadUInt16();
                    var numOfSections      = r.ReadInt16();
                    var StringSectionIndex = r.ReadUInt16();

                    List <SectionData> DataSections = new List <SectionData>();

                    // Parse Sections
                    var Sections = new ELFSection[numOfSections];
                    for (uint i = 0; i < numOfSections; i++)
                    {
                        r.Seek(sectionOffset + sectionHeaderSize * i);

                        Sections[i] = new ELFSection()
                        {
                            sh_name      = r.ReadUInt32(),
                            sh_type      = (SectionType)r.ReadInt32(),
                            sh_flags     = r.ReadUInt32(),
                            sh_addr      = r.ReadUInt32(),
                            sh_offset    = r.ReadUInt32(),
                            sh_size      = r.ReadUInt32(),
                            sh_link      = r.ReadUInt32(),
                            sh_info      = r.ReadUInt32(),
                            sh_addralign = r.ReadUInt32(),
                            sh_entsize   = r.ReadUInt32()
                        };

                        DataSections.Add(new SectionData());
                    }

                    // Parse Symbols
                    var symbolSection = Array.Find(Sections, e => r.ReadString((int)(Sections[StringSectionIndex].sh_offset + e.sh_name), -1) == ".symtab");

                    var Symbols = new ELFSymbol[symbolSection.sh_size / 0x10];
                    for (uint i = 0; i < Symbols.Length; i++)
                    {
                        r.Seek(symbolSection.sh_offset + 0x10 * i);

                        Symbols[i] = new ELFSymbol()
                        {
                            st_name  = r.ReadUInt32(),
                            st_value = r.ReadUInt32(),
                            st_size  = r.ReadUInt32(),
                            st_info  = r.ReadByte(),
                            st_other = r.ReadByte(),
                            st_shndx = r.ReadInt16()
                        };

                        SymbolSections.Add(new SymbolData());
                    }

                    // Grab Relocation Data

                    for (int i = 0; i < Sections.Length; i++)
                    {
                        var section = Sections[i];

                        var data = DataSections[i];
                        data.Name = r.ReadString((int)(Sections[StringSectionIndex].sh_offset + Sections[i].sh_name), -1);

                        data.Data = r.GetSection(section.sh_offset, (int)section.sh_size);

                        if (section.sh_type == SectionType.SHT_RELA || section.sh_type == SectionType.SHT_REL)
                        {
                            var relocs = ParseRelocationSection(r, section);

                            foreach (var v in relocs)
                            {
                                DataSections[(int)section.sh_info].Relocations.Add(new RelocData()
                                {
                                    Offset      = v.r_offset,
                                    AddEnd      = v.r_addend,
                                    Symbol      = SymbolSections[(int)v.R_SYM],
                                    Type        = (RelocType)v.R_TYP,
                                    SymbolIndex = v.R_SYM
                                });
                            }
                        }
                    }

                    var symbolStringSection = Sections[symbolSection.sh_link];

                    // rip out symbol data

                    for (int i = 0; i < Symbols.Length; i++)
                    {
                        var sym = Symbols[i];

                        var section = sym.st_shndx >= 0 ? DataSections[sym.st_shndx] : null;

                        byte[]           symbolData  = new byte[sym.st_size];
                        List <RelocData> relocations = new List <RelocData>();

                        if (section != null)
                        {
                            SymbolSections[i].SectionName = section.Name;

                            if (Sections[sym.st_shndx].sh_type == SectionType.SHT_NOBITS)
                            {
                                symbolData = new byte[section.Data.Length];
#if DEBUG
                                // Console.WriteLine($"{section.Name} {(Sections[sym.st_shndx].sh_offset + sym.st_value).ToString("X")} {sym.st_size} {sym.st_value} {symbolData.Length} {Sections[sym.st_shndx].sh_type}");
#endif
                            }
                            else
                            {
                                // If size of section is 0, get all data?
                                if (sym.st_size == 0)
                                {
                                    symbolData = section.Data;
                                }
                                //else
                                //if ((sym.st_value & 0x80000000) != 0)
                                //{
                                //    Array.Copy(section.Data, sym.st_value - 0x80000000 - Sections[sym.st_shndx].sh_offset, symbolData, 0, sym.st_size);
                                //    Debug.WriteLine($"LONG CALL {section.Relocations.Count} Off: {(sym.st_value - 0x80000000).ToString("X")} SectionOff: {Sections[sym.st_shndx].sh_offset.ToString("X")} {sym.st_value.ToString("X")} Size: {sym.st_size.ToString("X")} Total Size: {section.Data.Length.ToString("X")}");
                                //}
                                else
                                {
                                    Array.Copy(section.Data, sym.st_value, symbolData, 0, sym.st_size);
                                }

                                // TODO: when to get relocations?
                                relocations = section.Relocations.Where(
                                    e => e.Offset >= sym.st_value &&
                                    (e.Offset < sym.st_value + symbolData.Length)
                                    ).ToList();

                                // make relative
                                foreach (var rel in relocations)
                                {
                                    rel.Offset -= sym.st_value;
                                }
                            }

                            // if the offset is 0 the function is usually in another file
                            SymbolSections[i].External = Sections[sym.st_shndx].sh_offset == 0;
#if DEBUG
                            //Console.WriteLine(section.Name + " " + r.ReadString((int)(symbolStringSection.sh_offset + sym.st_name), -1)
                            //    + " " + Sections[sym.st_shndx].sh_info + " " + Sections[sym.st_shndx].sh_addr + " " + relocations.Count);

                            //Debug.WriteLine($"{section.Name} {r.ReadString((int)(symbolStringSection.sh_offset + sym.st_name), -1)} {(Sections[sym.st_shndx].sh_offset + + sym.st_value).ToString("X")} {sym.st_size.ToString("X")}");


                            if (section.Name == ".debug_line")
                            {
                                //r.Seek(Sections[sym.st_shndx].sh_offset + +sym.st_value);
                                //ParseDebugLine(r);
                            }
#endif
                        }

                        SymbolSections[i].Symbol      = r.ReadString((int)(symbolStringSection.sh_offset + sym.st_name), -1);
                        SymbolSections[i].Data        = symbolData;
                        SymbolSections[i].Relocations = relocations;
                    }
                }
        }