Exemple #1
0
        private static MiloFile ParseDirectory(Stream stream)
        {
            int version = stream.ReadInt32BE();

            if (!(version == 25 || version == 28)) // RBN1 and RBN2 milos
            {
                throw new NotSupportedException($"Milo directory version of {version} is not supported");
            }

            string   dirType = stream.ReadLengthUTF8(true), dirName = stream.ReadLengthUTF8(true);
            MiloFile milo = new MiloFile(dirType, dirName);

            stream.Position += 8; // Skips string count + total length

            // Reads entry types/names
            int count = stream.ReadInt32BE();

            string[] types = new string[count];
            string[] names = new string[count];

            for (int i = 0; i < count; i++)
            {
                types[i] = stream.ReadLengthUTF8(true);
                names[i] = stream.ReadLengthUTF8(true);
            }

            // Skips unknown data
            var next = FindNext(stream, ADDE_PADDING);

            stream.Seek(next + 4, SeekOrigin.Current);

            // Reads each file
            for (int i = 0; i < names.Length; i++)
            {
                long   start = stream.Position;
                int    size  = FindNext(stream, ADDE_PADDING);
                byte[] data  = stream.ReadBytes(size);
                stream.Position += 4;

                //milo.Entries.Add(new MiloEntry(names[i], types[i], stream.ReadBytes(size)));

                if (types[i].Equals("CharLipSync", StringComparison.CurrentCultureIgnoreCase))
                {
                    // Parse LipSync data
                    using (var ms = new MemoryStream(data))
                    {
                        CharLipSync lipsync = CharLipSync.FromStream(ms, names[i]);
                        milo.Entries.Add(lipsync);
                    }
                }
            }

            return(milo);
        }
Exemple #2
0
        public static CharLipSync FromStream(Stream stream, string name)
        {
            // Does not include DTA parsing so DC lipsync files are not supported at this time
            CharLipSync lipsync = new CharLipSync();

            lipsync._name = name;

            lipsync.Version    = stream.ReadInt32BE();
            lipsync.SubVersion = stream.ReadInt32BE();
            lipsync.DTAImport  = stream.ReadLengthUTF8(true);

            int dtb = stream.ReadByte();

            if (dtb != 0)
            {
                throw new Exception("Parsing of LipSync files with embedded DTB is not currently supported");
            }

            stream.Position += 4; // Skips zeros
            int visemeCount = stream.ReadInt32BE();

            lipsync.Visemes = Enumerable.Range(0, visemeCount).Select(x => stream.ReadLengthUTF8(true)).ToArray();

            int keyFrameCount = stream.ReadInt32BE();

            stream.Position += 4; // Skips total size of following data

            lipsync.Frames = new KeyFrame[keyFrameCount];
            for (int i = 0; i < keyFrameCount; i++)
            {
                int eventCount = stream.ReadByte();

                lipsync.Frames[i]        = new KeyFrame();
                lipsync.Frames[i].Events = new List <VisemeEvent>();

                for (int j = 0; j < eventCount; j++)
                {
                    lipsync.Frames[i].Events.Add(new VisemeEvent(lipsync.Visemes[stream.ReadByte()], (byte)stream.ReadByte()));
                }
            }

            // There's some other data ofter this sometimes but it's not needed

            return(lipsync);
        }