示例#1
0
        public void ReadRaw(BinaryReader br)
        {
            br.BaseStream.Seek(0, SeekOrigin.Begin);

            Objects   = new List <AnimationObject>();
            soundCues = new List <AnimationSoundCue>();

            //--Start

            //Row 1
            br.ReadUInt32(); //Unknown(mostly 85 CC 83 08) -
            br.ReadUInt64(); //Unknown(mostly 0) -
            br.ReadUInt32(); //File size

            //Row 2
            Length                = br.ReadUInt32();
            objectsNum            = br.ReadUInt32(); //Object num
            objectNamesOffsetsPos = br.ReadUInt32(); //Offset of object names offsets
            br.ReadUInt32();                         //Unknown / amount of something located in the offset defined in the first 4 bytes of row 3(like sound cues)

            //Row 3
            br.ReadUInt32();                           //Offset of unknown(can be 0 if the amount defined in last 4 bytes of row 2 are 0)
            soundCuesNum            = br.ReadUInt32();
            soundCueNamesOffsetsPos = br.ReadUInt32(); //Offset of offsets of sound cue names(contains some unknown floats also)
            objectPositionsNum      = br.ReadUInt32(); //Object num / amount of object positions offsets.

            //Row 4
            objectPositionsOffsetsPos = br.ReadUInt32(); //Offset of object positions offsets
            objectRotationsNum        = br.ReadUInt32(); //Objects num / amount of object rotations offsets.
            objectRotationsOffsetsPos = br.ReadUInt32(); //Offset of Object rotations offsets

            //--Object names offsets
            //each 4 bytes is an unsigned int.
            br.BaseStream.Seek(objectNamesOffsetsPos, SeekOrigin.Begin);
            for (int i = 0; i < objectsNum; i++)
            {
                uint namePos = br.ReadUInt32();
                if (namePos != 0)
                {
                    if (i == 0)
                    {
                        objectNamesPos = namePos;
                    }

                    long oldPos = br.BaseStream.Position;
                    br.BaseStream.Seek(namePos, SeekOrigin.Begin);

                    List <char> s = new List <char>();
                    char        c = ' ';
                    while (c != '\0')
                    {
                        c = br.ReadChar();
                        if (c != '\0')
                        {
                            s.Add(c);
                        }
                    }
                    Objects.Add(new AnimationObject(new string(s.ToArray())));

                    br.BaseStream.Seek(oldPos, SeekOrigin.Begin);
                }
            }

            //--Object names
            //pretty readable, separated by 00.

            if (soundCuesNum > 0)
            {
                br.BaseStream.Seek(soundCueNamesOffsetsPos, SeekOrigin.Begin);
                for (int i = 0; i < soundCuesNum; i++)
                {
                    float frame   = br.ReadSingle();
                    uint  namePos = br.ReadUInt32();
                    if (namePos != 0)
                    {
                        if (i == 0)
                        {
                            soundCueNamesPos = namePos;
                        }

                        long oldPos = br.BaseStream.Position;
                        br.BaseStream.Seek(namePos, SeekOrigin.Begin);

                        List <char> s = new List <char>();
                        char        c = ' ';
                        while (c != '\0')
                        {
                            c = br.ReadChar();
                            if (c != '\0')
                            {
                                s.Add(c);
                            }
                        }
                        soundCues.Add(new AnimationSoundCue(new string(s.ToArray()), frame));
                        br.BaseStream.Seek(oldPos, SeekOrigin.Begin);
                    }
                }

                //--Sound cue names offset
                br.ReadSingle(); // Unknown float
                soundCueNamesPos = br.ReadUInt32();

                //--Sound cue names
                //Pretty much the same as object names
            }

            //--Object positions offsets
            br.BaseStream.Seek(objectPositionsOffsetsPos, SeekOrigin.Begin);
            for (int i = 0; i < objectPositionsNum; i++)
            {
                br.ReadUInt32(); //Unknown / always E0 86 C6 1D
                uint vec3Pos = br.ReadUInt32();
                if (vec3Pos != 0)
                {
                    if (i == 0)
                    {
                        objectPositionsPos = vec3Pos;
                    }

                    AnimationObject animObj = Objects[i];

                    long oldPos = br.BaseStream.Position;
                    br.BaseStream.Seek(vec3Pos, SeekOrigin.Begin);

                    br.ReadUInt32();                                       //Unknown / always 0.
                    animObj.positionFrames = br.ReadUInt32();
                    br.BaseStream.Seek(br.ReadUInt32(), SeekOrigin.Begin); //It always points to the next 4 bytes but whatever.
                    //The first 4 bytes of each frame is 100% a growing float which is probably the frame but the othet two? no idea.

                    for (int x = 0; x < animObj.positionFrames; x++)
                    {
                        animObj.Positions.Add(new AnimPosition(br.ReadSingle(), br.ReadInt16(), br.ReadInt16(), br.ReadInt16(), br.ReadInt16()));
                    }

                    br.BaseStream.Seek(oldPos, SeekOrigin.Begin);
                }
            }

            //--Offsets of object rotations
            br.BaseStream.Seek(objectRotationsOffsetsPos, SeekOrigin.Begin);
            for (int i = 0; i < objectRotationsNum; i++)
            {
                br.ReadUInt32(); //Unknown / always B6 92 FB 9D or 5C B8 EC 96
                uint rotPos = br.ReadUInt32();
                if (rotPos != 0)
                {
                    if (i == 0)
                    {
                        objectRotationsPos = rotPos;
                    }

                    AnimationObject animObj = Objects[i];

                    long oldPos = br.BaseStream.Position;
                    br.BaseStream.Seek(rotPos, SeekOrigin.Begin);

                    br.ReadUInt32(); //Unknown / always 0.
                    animObj.rotationFrames = br.ReadUInt32();
                    br.BaseStream.Seek(br.ReadUInt32(), SeekOrigin.Begin);
                    for (int x = 0; x < animObj.rotationFrames; x++)
                    {
                        animObj.Rotations.Add(new AnimaRotation(br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle()));
                    }

                    br.BaseStream.Seek(oldPos, SeekOrigin.Begin);
                }
            }
        }
示例#2
0
        public void WriteRaw(BinaryWriter bw)
        {
            Console.WriteLine("Writing animation..");

            //Start
            //Row 1
            bw.Write(0x0883CC85);
            bw.Write((ulong)0);
            bw.Write(0); //Might be ignored by zlib compression or pd2 ignores it, adding the size to the last 4 bytes after compressing seems to make it work.

            //Row 2
            bw.Write(Length);
            bw.Write(Objects.Count);
            bw.Write(60); //Offset
            bw.Write(0);  //Amount of unknown

            //Row 3
            bw.Write(0);               //Unknown offset
            bw.Write(soundCues.Count); //Amount sound cue names offsets
            bw.Write(0);               //Sound cue names offset
            bw.Write(Objects.Count);   //Amount

            //Row 4
            bw.Write(0);             //Offset
            bw.Write(Objects.Count); //Amount
            bw.Write(0);             //Offset

            Console.WriteLine(Objects.Count);

            long lastObjectNameOffsetPos = bw.BaseStream.Position;

            for (int i = 0; i < Objects.Count; i++)
            {
                bw.Write(0); //Offset
            }

            long lastObjectNamePos = bw.BaseStream.Position;

            //Object names offsets + object names

            for (int i = 0; i < Objects.Count; i++)
            {
                bw.BaseStream.Seek(lastObjectNamePos, SeekOrigin.Begin);

                string name = Objects[i].Name;
                Console.WriteLine("Writing name '" + name + "'");
                for (int x = 0; x < name.Length; x++)
                {
                    bw.Write(name[x]);
                }
                bw.Write((byte)0);

                long nextObjectNamePos = bw.BaseStream.Position;

                bw.BaseStream.Seek(lastObjectNameOffsetPos, SeekOrigin.Begin);
                bw.Write((uint)lastObjectNamePos);

                lastObjectNamePos       = nextObjectNamePos;
                lastObjectNameOffsetPos = bw.BaseStream.Position;
            }


            bw.BaseStream.Seek(lastObjectNamePos, SeekOrigin.Begin);

            //Small thing for the animation to be almost the same as original
            long posCheck = (lastObjectNamePos % 4);

            if (posCheck > 0)
            {
                for (int i = 0; i < 4 - posCheck; i++)
                {
                    bw.Write((byte)0);
                }
            }

            //Sound cue names offsets + sound cue names

            if (soundCues.Count > 0)
            {
                long soundCuesPos = bw.BaseStream.Position;
                long lastSoundCueNameOffsetPos = soundCuesPos + 4;
                bw.BaseStream.Seek(40, SeekOrigin.Begin);
                bw.Write((uint)soundCuesPos);
                bw.BaseStream.Seek(soundCuesPos, SeekOrigin.Begin);

                for (int i = 0; i < soundCues.Count; i++)
                {
                    bw.Write(soundCues[i].Frame);
                    bw.Write(0); //Offset
                }


                long lastSoundCueNamePos = bw.BaseStream.Position;

                for (int i = 0; i < soundCues.Count; i++)
                {
                    bw.BaseStream.Seek(lastSoundCueNamePos, SeekOrigin.Begin);

                    string name = soundCues[i].Name;
                    Console.WriteLine("Writing sound cue name '" + name + "'");
                    for (int x = 0; x < name.Length; x++)
                    {
                        bw.Write(name[x]);
                    }
                    bw.Write((byte)0);

                    long nextSoundCueNamePos = bw.BaseStream.Position;

                    bw.BaseStream.Seek(lastSoundCueNameOffsetPos, SeekOrigin.Begin);
                    bw.Write((uint)lastSoundCueNamePos);

                    lastSoundCueNamePos       = nextSoundCueNamePos;
                    lastSoundCueNameOffsetPos = bw.BaseStream.Position + 4;
                }

                bw.BaseStream.Seek(lastSoundCueNamePos, SeekOrigin.Begin);

                posCheck = (lastSoundCueNamePos % 4);
                if (posCheck > 0)
                {
                    for (int i = 0; i < 4 - posCheck; i++)
                    {
                        bw.Write((byte)0);
                    }
                }
            }

            //Object positions offsets + object positions

            long positionsPos  = bw.BaseStream.Position;
            long lastOffsetPos = positionsPos + 4;

            bw.BaseStream.Seek(48, SeekOrigin.Begin);
            bw.Write((uint)positionsPos);
            bw.BaseStream.Seek(positionsPos, SeekOrigin.Begin);

            for (int i = 0; i < Objects.Count; i++)
            {
                bw.Write(0x1DC686E0); //Unknown
                bw.Write(0);          //Offset
            }

            long lastPos = bw.BaseStream.Position;

            for (int i = 0; i < Objects.Count; i++)
            {
                bw.BaseStream.Seek(lastPos, SeekOrigin.Begin);
                AnimationObject animObject = Objects[i];

                Console.WriteLine("Writing positions for " + animObject.Name);

                bw.Write(0); //Unknown / always 0.
                bw.Write(animObject.Positions.Count);
                bw.Write((uint)bw.BaseStream.Position + 4);
                for (int x = 0; x < animObject.Positions.Count; x++)
                {
                    Console.WriteLine("Position #" + x + 1 + " offset " + bw.BaseStream.Position);
                    animObject.Positions[x].Write(bw);
                }

                long nextPos = bw.BaseStream.Position;

                bw.BaseStream.Seek(lastOffsetPos, SeekOrigin.Begin);
                bw.Write((uint)lastPos);

                lastPos       = nextPos;
                lastOffsetPos = bw.BaseStream.Position + 4;
            }

            bw.BaseStream.Seek(lastPos, SeekOrigin.Begin);

            //Object rotations offsets + object rotations

            long rotationsPos = bw.BaseStream.Position;

            lastOffsetPos = rotationsPos + 4;
            bw.BaseStream.Seek(56, SeekOrigin.Begin);
            bw.Write((uint)rotationsPos);
            bw.BaseStream.Seek(rotationsPos, SeekOrigin.Begin);

            for (int i = 0; i < Objects.Count; i++)
            {
                bw.Write(0x9DFB92B6); //Unknown
                bw.Write(0);          //Offset
            }

            lastPos = bw.BaseStream.Position;

            for (int i = 0; i < Objects.Count; i++)
            {
                bw.BaseStream.Seek((uint)lastPos, SeekOrigin.Begin);
                AnimationObject animObject = Objects[i];

                Console.WriteLine("Writing rotations for " + animObject.Name);

                bw.Write(0); //Unknown / always 0.
                bw.Write(animObject.Rotations.Count);
                bw.Write((uint)bw.BaseStream.Position + 4);
                for (int x = 0; x < animObject.Rotations.Count; x++)
                {
                    Console.WriteLine("Rotation #" + x + 1 + " offset " + bw.BaseStream.Position);
                    animObject.Rotations[x].Write(bw);
                }

                long nextPos = bw.BaseStream.Position;

                bw.BaseStream.Seek(lastOffsetPos, SeekOrigin.Begin);
                bw.Write((uint)lastPos);

                lastPos       = nextPos;
                lastOffsetPos = bw.BaseStream.Position + 4;
            }

            bw.BaseStream.Seek(lastPos, SeekOrigin.Begin);
        }