예제 #1
0
            public void Read(BinaryReaderExt reader)
            {
                reader.ReadChars(4);
                dwSize              = reader.ReadUInt32();
                dwFlags             = (DDSD)reader.ReadUInt32();
                dwHeight            = reader.ReadInt32();
                dwWidth             = reader.ReadInt32();
                dwPitchOrLinearSize = reader.ReadInt32();
                dwDepth             = reader.ReadInt32();
                dwMipMapCount       = reader.ReadInt32();
                dwReserved1         = new uint[11];
                for (int i = 0; i < 11; i++)
                {
                    dwReserved1[i] = reader.ReadUInt32();
                }
                ddspf.Read(reader);
                dwCaps      = (DDSCAPS)reader.ReadInt32();
                dwCaps2     = (DDSCAPS2)reader.ReadInt32();
                dwCaps3     = reader.ReadUInt32();
                dwCaps4     = reader.ReadUInt32();
                dwReserved2 = reader.ReadUInt32();

                if (ddspf.dwFlags.HasFlag(DDPF.FOURCC) && ddspf.dwFourCC == 0x30315844)
                {
                    DXT10Header.Read(reader);
                }
            }
예제 #2
0
        /// <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);
                }
            }
        }
예제 #3
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);
        }
예제 #4
0
        public void Open(string FileName)
        {
            using (BinaryReaderExt stream = new BinaryReaderExt(new FileStream(FileName, FileMode.Open)))
            {
                stream.BigEndian = true;

                Heading      = stream.ReadInt32();
                VersionMinor = stream.ReadByte();
                VersionMajor = stream.ReadByte();
                Magic        = new string(stream.ReadChars(4));

                stream.ReadByte();
                var collisionCount = stream.ReadInt32();
                for (int i = 0; i < collisionCount; i++)
                {
                    LVDCollision col = new LVDCollision();
                    col.Read(stream, VersionMinor);
                    Collisions.Add(col);
                }

                stream.ReadByte();
                var spawnCount = stream.ReadInt32();
                for (int i = 0; i < spawnCount; i++)
                {
                    LVDSpawn spawn = new LVDSpawn();
                    spawn.Read(stream);
                    Spawns.Add(spawn);
                }

                stream.ReadByte();
                var respawnCount = stream.ReadInt32();
                for (int i = 0; i < respawnCount; i++)
                {
                    LVDSpawn respawn = new LVDSpawn();
                    respawn.Read(stream);
                    Respawns.Add(respawn);
                }

                stream.ReadByte();
                var boundsCount = stream.ReadInt32();
                for (int i = 0; i < boundsCount; i++)
                {
                    LVDBounds bound = new LVDBounds();
                    bound.Read(stream);
                    CameraBounds.Add(bound);
                }

                stream.ReadByte();
                var blastCount = stream.ReadInt32();
                for (int i = 0; i < blastCount; i++)
                {
                    LVDBounds blast = new LVDBounds();
                    blast.Read(stream);
                    BlastZoneBounds.Add(blast);
                }

                stream.ReadByte();
                int enemyGenCount = stream.ReadInt32();
                for (int i = 0; i < enemyGenCount; i++)
                {
                    LVDEnemyGenerator enGen = new LVDEnemyGenerator();
                    enGen.Read(stream);
                    EnemyGenerators.Add(enGen);
                }

                stream.ReadByte();
                if (stream.ReadInt32() > 0)
                {
                    throw new NotImplementedException("Unknown LVD Section at 0x" + stream.BaseStream.Position.ToString("X"));
                }

                stream.ReadByte();
                if (stream.ReadInt32() > 0)
                {
                    throw new NotImplementedException("Unknown LVD Section at 0x" + stream.BaseStream.Position.ToString("X"));
                }

                stream.ReadByte();
                if (stream.ReadInt32() > 0)
                {
                    throw new NotImplementedException("Unknown LVD Section at 0x" + stream.BaseStream.Position.ToString("X"));
                }

                stream.ReadByte();
                if (stream.ReadInt32() > 0)
                {
                    throw new NotImplementedException("Unknown LVD Section at 0x" + stream.BaseStream.Position.ToString("X"));
                }

                stream.ReadByte();
                if (stream.ReadInt32() > 0)
                {
                    throw new NotImplementedException("Unknown LVD Section at 0x" + stream.BaseStream.Position.ToString("X"));
                }

                stream.ReadByte();
                int damageCount = stream.ReadInt32();
                for (int i = 0; i < damageCount; i++)
                {
                    LVDDamageShape shape = new LVDDamageShape();
                    shape.Read(stream);
                    DamageShapes.Add(shape);
                }

                stream.ReadByte();
                int itemSpawnCount = stream.ReadInt32();
                for (int i = 0; i < itemSpawnCount; i++)
                {
                    LVDItemSpawner spawn = new LVDItemSpawner();
                    spawn.Read(stream);
                    ItemSpawners.Add(spawn);
                }

                if (VersionMinor > 0xA)
                {
                    stream.ReadByte();
                    int genCurveCount = stream.ReadInt32();
                    for (int i = 0; i < genCurveCount; i++)
                    {
                        LVDRangeCurve point = new LVDRangeCurve();
                        point.Read(stream);
                        RangeCurves.Add(point);
                    }

                    stream.ReadByte();
                    int genCurveCount2 = stream.ReadInt32();
                    for (int i = 0; i < genCurveCount2; i++)
                    {
                        LVDGeneralVector point = new LVDGeneralVector();
                        point.Read(stream);
                        GeneralVectors.Add(point);
                    }
                }

                stream.ReadByte();
                int genShapeCount = stream.ReadInt32();
                for (int i = 0; i < genShapeCount; i++)
                {
                    LVDGeneralShape shape = new LVDGeneralShape();
                    shape.Read(stream);
                    GeneralShapes.Add(shape);
                }

                stream.ReadByte();
                int genPointCount = stream.ReadInt32();
                for (int i = 0; i < genPointCount; i++)
                {
                    LVDGeneralPoint point = new LVDGeneralPoint();
                    point.Read(stream);
                    GeneralPoints.Add(point);
                }

                stream.ReadByte();
                if (stream.ReadInt32() > 0)
                {
                    throw new NotImplementedException("Unknown LVD Section at 0x" + stream.BaseStream.Position.ToString("X"));
                }

                stream.ReadByte();
                if (stream.ReadInt32() > 0)
                {
                    throw new NotImplementedException("Unknown LVD Section at 0x" + stream.BaseStream.Position.ToString("X"));
                }

                stream.ReadByte();
                if (stream.ReadInt32() > 0)
                {
                    throw new NotImplementedException("Unknown LVD Section at 0x" + stream.BaseStream.Position.ToString("X"));
                }

                stream.ReadByte();
                if (stream.ReadInt32() > 0)
                {
                    throw new NotImplementedException("Unknown LVD Section at 0x" + stream.BaseStream.Position.ToString("X"));
                }

                if (VersionMinor > 0xA)
                {
                    stream.ReadByte();
                    var shrunkboundsCount = stream.ReadInt32();
                    for (int i = 0; i < shrunkboundsCount; i++)
                    {
                        LVDBounds bound = new LVDBounds();
                        bound.Read(stream);
                        ShrunkCameraBounds.Add(bound);
                    }

                    stream.ReadByte();
                    var shrunkblastCount = stream.ReadInt32();
                    for (int i = 0; i < shrunkblastCount; i++)
                    {
                        LVDBounds blast = new LVDBounds();
                        blast.Read(stream);
                        ShrunkBlastZoneBounds.Add(blast);
                    }
                }

                if (stream.BaseStream.Length != stream.BaseStream.Position)
                {
                    stream.PrintPosition();
                    throw new Exception("Error fully parsing LVD " + stream.BaseStream.Position.ToString("X"));
                }
            }
        }
예제 #5
0
        /// <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);
        }
예제 #6
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();
                }
        }
예제 #7
0
        /// <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);
        }