コード例 #1
0
ファイル: Program.cs プロジェクト: gdkchan/MGSDATool
        /// <summary>
        ///     Inserts extracted subtitles into a movie.dat.
        /// </summary>
        /// <param name="Movie">The movie.dat file path</param>
        /// <param name="Input">The input folder with subtitles in XML</param>
        /// <param name="Game">The game being tampered (MGS3 or MGS4)</param>
        private static void Insert(string Movie, string Input, MGSGame Game)
        {
            string[] Files = Directory.GetFiles(Input);
            MGSText.Initialize();

            string     NewFile = Path.GetTempFileName();
            FileStream In      = new FileStream(Movie, FileMode.Open);
            FileStream Out     = new FileStream(NewFile, FileMode.Create);

            Endian Endian = Endian.Default;

            switch (Game)
            {
            case MGSGame.MGSTS:
                Endian = Endian.Big;
                Game   = MGSGame.MGS3;
                break;

            case MGSGame.MGS3: Endian = Endian.Little; break;

            case MGSGame.MGS4: Endian = Endian.Big; break;
            }

            EndianBinaryReader Reader = new EndianBinaryReader(In, Endian);
            EndianBinaryWriter Writer = new EndianBinaryWriter(Out, Endian);

            int           Index    = 0;
            int           SubIndex = 0;
            MovieSubtitle Subtitle = GetSubtitle(Files[0]);

            while (In.Position < In.Length)
            {
                StreamPacket Packet = StreamPacket.FromStream(Reader, Game);

                switch (Packet.Type)
                {
                case PacketType.Subtitle: SubtitlePacket.ToStream(Writer, Subtitle.Subtitles[SubIndex++], Game); break;

                case PacketType.EndOfStream:
                    if (++Index < Files.Length)
                    {
                        Subtitle = GetSubtitle(Files[Index]);
                    }
                    SubIndex = 0;
                    break;
                }

                if (Packet.Type != PacketType.Subtitle)
                {
                    StreamPacket.ToStream(Writer, Packet, Game);
                }

                ReportProgress((float)In.Position / In.Length);
            }

            In.Close();
            Out.Close();

            File.Delete(Movie);
            File.Move(NewFile, Movie);
            File.Delete(NewFile);
        }
コード例 #2
0
ファイル: Speech.cs プロジェクト: gdkchan/MGSDATool
        /// <summary>
        ///     Extracts the subtitles from a *.spc file to a *.xml file.
        /// </summary>
        /// <param name="Speech">The input *.spc file Stream</param>
        /// <param name="OutFile">The output *.xml file path</param>
        public static void Extract(Stream Speech, string OutFile)
        {
            SpeechSubtitle     Output = new SpeechSubtitle();
            EndianBinaryReader Reader = new EndianBinaryReader(Speech, Endian.Big);

            int  Index        = 0;
            uint HeaderOffset = GetHeaderPosition(Reader);

            while (Speech.Position < Speech.Length)
            {
                Speech.Seek(HeaderOffset + Index * 0x20, SeekOrigin.Begin);

                uint  Id             = Reader.ReadUInt32();
                uint  WaveOffset     = Reader.ReadUInt32() << 11;
                uint  WaveLength     = Reader.ReadUInt32() << 11;
                float WaveSynchro    = Reader.ReadSingle();
                uint  SubtitleOffset = Reader.ReadUInt32() + WaveOffset;
                uint  SubtitleLength = Reader.ReadUInt32();
                uint  TableLength    = Reader.ReadUInt32();

                if (Id == 0 || Speech.Position >= Speech.Length)
                {
                    break;
                }

                if (SubtitleLength > 0)
                {
                    SpeechDialog Dialog = new SpeechDialog();
                    Speech.Seek(SubtitleOffset, SeekOrigin.Begin);

                    while (true)
                    {
                        SubtitlePacket Subtitle = SubtitlePacket.FromStream(Reader);
                        if (Subtitle != null)
                        {
                            Dialog.Subtitles.Add(Subtitle);
                        }
                        if (Speech.Position >= SubtitleOffset + SubtitleLength || Subtitle == null)
                        {
                            break;
                        }
                    }

                    Output.Dialogs.Add(Dialog);
                }

                Index++;
            }

            XmlSerializerNamespaces NameSpaces = new XmlSerializerNamespaces();

            NameSpaces.Add(string.Empty, string.Empty);
            XmlWriterSettings Settings = new XmlWriterSettings
            {
                Encoding = Encoding.UTF8,
                Indent   = true
            };

            XmlSerializer Serializer = new XmlSerializer(typeof(SpeechSubtitle));

            using (FileStream OutputStream = new FileStream(OutFile, FileMode.Create))
            {
                XmlWriter Writer = XmlWriter.Create(OutputStream, Settings);
                Serializer.Serialize(Writer, Output, NameSpaces);
            }
        }
コード例 #3
0
 void ffmpegSubtitleSupport_SubtitlePopulatedEvent(SubtitleSupport sender, SubtitlePacket subtitlePacket)
 {
     MessengerInstance.Send <Message>(new Message("SubtitleInFFmpeg", subtitlePacket), TransportControlViewModel.NAME);
 }
コード例 #4
0
ファイル: Speech.cs プロジェクト: gdkchan/MGSDATool
        /// <summary>
        ///     Inserts the subtitles from a *.xml into a *.spc file.
        /// </summary>
        /// <param name="Speech">The output *.spc file Stream</param>
        /// <param name="InFile">The input *.xml file path</param>
        public static void Insert(Stream Speech, string InFile)
        {
            SpeechSubtitle Input;
            XmlSerializer  Deserializer = new XmlSerializer(typeof(SpeechSubtitle));

            using (FileStream InputStream = new FileStream(InFile, FileMode.Open))
            {
                Input = (SpeechSubtitle)Deserializer.Deserialize(InputStream);
            }

            EndianBinaryReader Reader = new EndianBinaryReader(Speech, Endian.Big);

            using (MemoryStream Output = new MemoryStream())
            {
                MemoryStream       Header = new MemoryStream();
                EndianBinaryWriter Writer = new EndianBinaryWriter(Header, Endian.Big);

                int  Index        = 0;
                int  SubIndex     = 0;
                long DataOffset   = 0;
                uint HeaderOffset = GetHeaderPosition(Reader);
                while (Speech.Position < Speech.Length)
                {
                    Speech.Seek(HeaderOffset + Index * 0x20, SeekOrigin.Begin);

                    uint  Id             = Reader.ReadUInt32();
                    uint  WaveOffset     = Reader.ReadUInt32() << 11;
                    uint  WaveLength     = Reader.ReadUInt32() << 11;
                    float WaveSynchro    = Reader.ReadSingle();
                    uint  SubtitleOffset = Reader.ReadUInt32() + WaveOffset;
                    uint  SubtitleLength = Reader.ReadUInt32();
                    uint  TableLength    = Reader.ReadUInt32();

                    if (Id == 0 || Speech.Position >= Speech.Length)
                    {
                        break;
                    }

                    Speech.Seek(WaveOffset + 8, SeekOrigin.Begin);
                    WaveLength = Reader.ReadUInt32();
                    byte[] WaveBuffer = new byte[WaveLength];
                    Speech.Seek(WaveOffset, SeekOrigin.Begin);
                    Speech.Read(WaveBuffer, 0, WaveBuffer.Length);

                    Output.Seek(DataOffset, SeekOrigin.Begin);
                    Output.Write(WaveBuffer, 0, WaveBuffer.Length);

                    if (SubtitleLength > 0)
                    {
                        SubtitleLength = 0;

                        foreach (SubtitlePacket Subtitle in Input.Dialogs[SubIndex++].Subtitles)
                        {
                            byte[] SubtitleBuffer = SubtitlePacket.ToBytes(Subtitle);
                            SubtitleLength += (uint)SubtitleBuffer.Length;
                            Output.Write(SubtitleBuffer, 0, SubtitleBuffer.Length);
                        }
                    }

                    Speech.Seek(SubtitleOffset + SubtitleLength, SeekOrigin.Begin);
                    byte[] TableBuffer = new byte[TableLength];
                    Speech.Read(TableBuffer, 0, TableBuffer.Length);
                    Output.Write(TableBuffer, 0, TableBuffer.Length);

                    while ((Output.Position & 0x7ff) != 0)
                    {
                        Output.WriteByte(0);
                    }

                    Writer.Write(Id);
                    Writer.Write((uint)(DataOffset >> 11));
                    Writer.Write((uint)((Output.Position - DataOffset) >> 11));
                    Writer.Write(WaveSynchro);
                    Writer.Write(WaveLength);
                    Writer.Write(SubtitleLength);
                    Writer.Write(TableLength);
                    Writer.Write(0u);

                    DataOffset = Output.Position;
                    Index++;
                }

                Output.Write(Header.ToArray(), 0, (int)Header.Length);
                while ((Output.Position & 0x7ff) != 0)
                {
                    Output.WriteByte(0);
                }
                Header.Dispose();

                Speech.SetLength(0);
                Speech.Write(Output.ToArray(), 0, (int)Output.Length);
            }
        }