Exemplo n.º 1
0
        public void Access(string Path, Action Action, int RecompressVersion = -1)
        {
            if (Path.Contains('/'))
            {
                var Parts = Path.Split(new[] { '/' }, 2);
                Access(Parts[0], () =>
                {
                    Access(Parts[1], Action);
                });
                return;
            }

            GetFile(Path, (CompressedStream) =>
            {
                DecompressAndRecompressIfRequired(CompressedStream, (UncompressedStream) =>
                {
                    var Magic = UncompressedStream.Slice().ReadBytesUpTo(0x100);
                    if (FPS4.IsValid(Magic))
                    {
                        LanguageUtils.LocalSet(ref this.FileSystem, new FPS4FileSystem(UncompressedStream), Action);
                    }
                    else if (TO8SCEL.IsValid(Magic))
                    {
                        LanguageUtils.LocalSet(ref this.FileSystem, new TO8SCELFileSystem(UncompressedStream), Action);
                    }
                    else
                    {
                        throw (new InvalidOperationException(String.Format("Can't access '{0}'", Path)));
                    }
                }, RecompressVersion);
            }, RecompressVersion);
        }
Exemplo n.º 2
0
        public void RepackBtlPack()
        {
            //var OldFps4 = new FPS4(OldStream.Slice());
            //var NewFps4 = new FPS4(OldStream.Slice()); // Intended OldStream

            Patcher.Action("Packing BTL_PACK_ES.DAT", () =>
            {
                Patcher.TempFS.OpenFileReadScope("BTL_PACK_UK.DAT", (OldStream) =>
                {
                    Patcher.TempFS.OpenFileCreateScope("BTL_PACK_ES.DAT", (NewStream) =>
                    {
                        var OldFps4 = new FPS4(OldStream.Slice());
                        var NewFps4 = new FPS4(OldStream.Slice());                         // Intended OldStream

                        NewFps4.ClearAllEntries();

                        for (int n = 0; n <= 19; n++)
                        {
                            NewFps4.CreateEntry(String.Format("{0}", n), Patcher.TempFS.OpenFileRead(String.Format("BTL_PACK/{0}", n)));
                        }

                        NewFps4.SaveTo(NewStream, DoAlign: false);
                    });
                });
            });
        }
Exemplo n.º 3
0
        protected void ExtractSvo(string SvoPath)
        {
            //try
            //{
            using (var _SvoStream = File.OpenRead(SvoPath))
            {
                Stream SvoStream  = _SvoStream;
                int    Compressed = TalesCompression.DetectVersion(SvoStream.Slice().ReadBytes(16), SvoStream.Length);
                if (Compressed >= 0)
                {
                    SvoStream = TalesCompression.DecompressStream(SvoStream);
                }

                if (SvoStream.SliceWithLength().ReadString(7) == "TO8SCEL")
                {
                    var TO8SCEL = new TO8SCEL(SvoStream);

                    foreach (var Entry in TO8SCEL)
                    {
                        Console.WriteLine("{0} ... Start: {1}, End: {2}, Length: {3}", Entry.Index, Entry.EntryStruct.Offset, Entry.EntryStruct.Offset + Entry.EntryStruct.LengthCompressed, Entry.EntryStruct.LengthCompressed);
                    }
                }
                else
                {
                    var FPS4 = new FPS4(SvoStream);

                    Console.WriteLine("{0}", FPS4);

                    foreach (var Entry in FPS4)
                    {
                        Console.WriteLine("{0} ... Start: {1}, End: {2}, Length: {3}", Entry.Name, Entry.EntryStruct.Offset, Entry.EntryStruct.Offset + Entry.EntryStruct.LengthReal, Entry.EntryStruct.LengthReal);
                    }
                }
            }
        }
Exemplo n.º 4
0
        private void Handle3()
        {
            Patcher.TempFS.OpenFileRWScope("BTL_PACK_ES.DAT", (BtlPackUkStream) =>
            {
                Patcher.GameSetFileSystem(new FPS4FileSystem(BtlPackUkStream), () =>
                {
                    HandleBattlePackImages();
                });
            });

            var OldBtlSvo = new FPS4(Patcher.GameFileSystem.OpenFileRead("btl.svo"));
            var NewBtlSvo = new FPS4(Patcher.GameFileSystem.OpenFileRead("btl.svo"));

            NewBtlSvo.ClearAllEntries();
            NewBtlSvo.CreateEntry("BTL_EFFECT.DAT", OldBtlSvo["BTL_EFFECT.DAT"].Open());
            var PackEsEntry = NewBtlSvo.CreateEntry("BTL_PACK_ES.DAT", Patcher.TempFS.OpenFileRead("BTL_PACK_ES.DAT"));

            NewBtlSvo.CreateEntry("BTL_PACK_DE.DAT", PackEsEntry);
            NewBtlSvo.CreateEntry("BTL_PACK_FR.DAT", PackEsEntry);
            NewBtlSvo.CreateEntry("BTL_PACK_UK.DAT", PackEsEntry);
            NewBtlSvo.CreateEntry("BTL_PACK_US.DAT", PackEsEntry);
            Patcher.TempFS.OpenFileCreateScope("btl.svo", (NewBtlSvoStream) =>
            {
                NewBtlSvo.SaveTo(NewBtlSvoStream);
            });

            Patcher.GameReplaceFile("btl.svo", Patcher.TempFS.OpenFileRead("btl.svo"));
        }
Exemplo n.º 5
0
 protected void Init(Stream StreamChatSvoOriginal, Stream StreamChatSvoTranslate, Stream StreamAcmeSkits)
 {
     //TalesCompression = new TalesCompression1_3(3);
     TalesCompression = new TalesCompression15_Lzx();
     PAK       = new FPS4(StreamChatSvoOriginal);
     PAKOutput = StreamChatSvoTranslate;
     ACME1     = new ACME1(StreamAcmeSkits, Encoding.GetEncoding("ISO-8859-1"));
 }
Exemplo n.º 6
0
 public override string ToString()
 {
     using (FPS4 fps4 = new FPS4(Stream.Duplicate()))
         using (DuplicatableStream txmvStream = fps4.GetChildByIndex(1).AsFile.DataStream.Duplicate())
             using (FPS4 txmv = new FPS4(txmvStream.Duplicate()))
                 using (DuplicatableStream txmStream = txmv.GetChildByIndex(0).AsFile.DataStream.Duplicate()) {
                     TXM txm = new TXM(txmStream.Duplicate());
                     return(txm.TXMRegulars[0].Name);
                 }
 }
Exemplo n.º 7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="DatPath"></param>
        /// <param name="DavPath"></param>
        /// <param name="OutputDirectory"></param>
        protected void ExtractSvo2(string DatPath, string DavPath, string OutputDirectory = null)
        {
            if (DavPath == null)
            {
                DavPath = DatPath;
            }

            if (OutputDirectory == null)
            {
                OutputDirectory = DatPath + ".d";
            }

            Console.WriteLine("Loading {0}...", DatPath);
            //try
            //{
            using (var _Stream1 = File.OpenRead(DatPath))
                using (var Stream2 = File.OpenRead(DavPath))
                {
                    var Stream1 = (Stream)_Stream1;
                    try { Directory.CreateDirectory(OutputDirectory); }
                    catch { }

                    int Compressed = TalesCompression.DetectVersion(Stream1.Slice().ReadBytes(16), Stream1.Length);
                    if (Compressed >= 0)
                    {
                        Stream1 = TalesCompression.DecompressStream(Stream1);
                    }

                    if (Stream1.SliceWithLength().ReadString(7) == "TO8SCEL")
                    {
                        var TO8SCEL = new TO8SCEL(Stream1);

                        foreach (var Entry in TO8SCEL)
                        {
                            _ExtractFile(OutputDirectory + "/" + Entry.Index, () => Entry.UncompressedStream, (int)(uint)Entry.EntryStruct.Offset, (int)(uint)Entry.EntryStruct.LengthCompressed);
                        }
                    }
                    else
                    {
                        var FPS4 = new FPS4(Stream1, Stream2);

                        Console.WriteLine("{0}", FPS4);

                        foreach (var Entry in FPS4)
                        {
                            _ExtractFile(OutputDirectory + "/" + Entry.Name, () => Entry.Open(), (int)(uint)Entry.EntryStruct.Offset, (int)(uint)Entry.EntryStruct.LengthReal);
                        }
                    }
                }
            //}
            //catch (Exception Exception)
            //{
            //	Console.Error.WriteLine("{0}", Exception);
            //}
        }
Exemplo n.º 8
0
        public void Handle()
        {
            Patcher.Action("chat.svo", () =>
            {
                TranslatedChatSvo = new FPS4(Patcher.GameFileSystem.OpenFileRead("chat.svo")).ClearAllEntries();
                OriginalChatSvo   = new FPS4(Patcher.GameFileSystem.OpenFileRead("chat.svo"));

                Patcher.ProgressHandler.ExecuteActionsWithProgressTracking("chat.svo",
                                                                           Handle1,
                                                                           Handle2,
                                                                           Handle3
                                                                           );
            });
        }
Exemplo n.º 9
0
        static string svoExtractToTempDir(string infile, bool nometa = false)
        {
            string extractPath = TempUtil.GetTempFileName();

            if (Directory.Exists(extractPath))
            {
                Util.DeleteDirectoryAggressive(extractPath, true);
            }
            Directory.CreateDirectory(extractPath);
            using (var fps4 = new FPS4(infile)) {
                fps4.Extract(extractPath, nometa);
            }
            Logger.LogDirData(extractPath, "FPS4 extract of " + infile);
            return(extractPath);
        }
Exemplo n.º 10
0
        private static void OperationExtractFPS4()
        {
            string filename = ConsolePath("Full path to FPS4 archive..?");

            if (filename.IsEmpty())
            {
                return;
            }
            Stream stream = new CachedReadStream(new FileStream(filename, FileMode.Open, FileAccess.Read));
            FPS4   fps    = new FPS4(stream);
            string path   = Path.Combine(Path.GetDirectoryName(filename), Path.GetFileName(filename) + ".ext");

            fps.Root.Extract(path);
            stream.Close();

            File.WriteAllText(Path.Combine(path, "fps4.type"), fps.Type);
        }
Exemplo n.º 11
0
        public static Stream ProcessAreaNameTexture(FileFetcher _fc, string name, DuplicatableStream jstream, DuplicatableStream ustream)
        {
            DuplicatableStream wstream     = _fc.GetFile(name, Version.W);
            FPS4               wani        = new FPS4(wstream.Duplicate());
            FPS4               uani        = new FPS4(new HyoutaTools.Tales.tlzc.TlzcDecompressor().Decompress(ustream.Duplicate()));
            var                clgfileinfo = wani.Files.Where(x => x.FileName.EndsWith(".CLG")).First();
            string             clgname     = clgfileinfo.FileName;
            FPS4               waniclg     = new FPS4(wani.GetChildByName(clgname).AsFile.DataStream);
            FPS4               uaniclg     = new FPS4(uani.GetChildByName(clgname).AsFile.DataStream);
            DuplicatableStream wtexstream  = waniclg.GetChildByIndex(1).AsFile.DataStream;
            DuplicatableStream utexstream  = uaniclg.GetChildByIndex(1).AsFile.DataStream;

            Stream wtexstreammod = ProcessTexture(name + "/" + clgname, utexstream, wtexstream);

            long   injectOffset = clgfileinfo.Location.Value + waniclg.Files[1].Location.Value;
            Stream wstreammod   = wstream.CopyToMemory();

            wstreammod.Position    = injectOffset;
            wtexstreammod.Position = 0;
            StreamUtils.CopyStream(wtexstreammod, wstreammod, wtexstreammod.Length);
            wstreammod.Position = 0;
            return(wstreammod);
        }
Exemplo n.º 12
0
        protected void CsvHandle(string CsvPath)
        {
            var ListLastPair        = new HashSet <string>();
            var ProcessedNormalFile = new HashSet <string>();
            var FPS4List            = new Dictionary <string, FPS4>();
            var Parse = new Regex(@"ReadFile"",""([^""]+)"",""SUCCESS"",""Offset: ([\d\.]+), Length: ([\d\.]+)", RegexOptions.Compiled);

            foreach (var Line in File.ReadAllLines(CsvPath))
            {
                if (Line.Contains(@"ReadFile"))
                {
                    var Match = Parse.Match(Line);
                    if (Match.Groups[1].Value == "")
                    {
                        //Console.WriteLine(Line);
                        Console.Error.WriteLine("Invalid Line! : {0}", Line);
                    }
                    else
                    {
                        var FilePath = Match.Groups[1].Value;
                        var Offset   = int.Parse(Match.Groups[2].Value.Replace(".", "").Trim());
                        var Length   = int.Parse(Match.Groups[3].Value.Replace(".", "").Trim());
                        if (!FPS4List.ContainsKey(FilePath))
                        {
                            try {
                                FPS4List[FilePath] = new FPS4(File.OpenRead(FilePath));
                            } catch {
                            }
                        }
                        if (FPS4List.ContainsKey(FilePath))
                        {
                            var FPS4 = FPS4List[FilePath];
                            foreach (var Item in FPS4)
                            {
                                if (Offset >= Item.EntryStruct.Offset && Offset < Item.EntryStruct.Offset + Item.EntryStruct.LengthReal)
                                {
                                    var CurrentPair = FilePath + Item.Name;
                                    if (!ListLastPair.Contains(CurrentPair))
                                    {
                                        ListLastPair.Add(CurrentPair);
                                        Console.WriteLine("{0}: {1}, {2} : {3}", FilePath, Offset, Length, Item.Name);
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (!ProcessedNormalFile.Contains(FilePath))
                            {
                                ProcessedNormalFile.Add(FilePath);
                                Console.WriteLine("{0}: {1}, {2}", FilePath, Offset, Length);
                            }
                        }
                    }

                    //var Parts = Line.Split(',');
                    //Console.WriteLine(Parts[5]);
                    //Console.WriteLine(Parts[7]);
                    //Console.WriteLine(Parts[8]);
                    //Console.WriteLine(String.Join("||", Parts));
                }
            }
        }
Exemplo n.º 13
0
        private static void OperationPackFPS4()
        {
            string dirname = ConsolePath("Full path to FPS4 file contents..?");
            string filename;

            if (dirname.EndsWith(".ext"))
            {
                filename = dirname.Substring(0, dirname.Length - 4);
            }
            else
            {
                filename = ConsolePath("Full path to FPS4 archive..?");
            }

            if (!File.Exists(filename))
            {
                Console.WriteLine("FPS4 file does not exist.");
                return;
            }

            Stream stream = new CachedReadStream(new FileStream(filename, FileMode.Open, FileAccess.Read));

            FPS4 fps = new FPS4(stream);

            DelayedStreamCache cache = new DelayedStreamCache();

            string[] files = Directory.GetFiles(dirname, "*", SearchOption.TopDirectoryOnly);
            foreach (string file in files)
            {
                string        fname = Path.GetFileName(file);
                FPS4Base.Node node  = fps.Base.Nodes.FirstOrDefault(n => n.Filename == fname);

                Stream data = new FileStream(file, FileMode.Open, FileAccess.Read);
                cache.AddStream(data);

                if (node == null)
                {
                    continue;

                    /* TODO: Only add when we want to
                     * node = new FPS4Base.Node(0, (uint)data.Length, (uint)data.Length, fname, 0, 0, data);
                     * fps.Base.Nodes.Insert((int)fps.Base.Files - 1, node);
                     * fps.Base.Files++;
                     */
                }
                else
                {
                    node.Data = data;
                }
            }

            fps.Base.Reorder();

            Stream ostream = new FileStream(filename + ".new", FileMode.Create, FileAccess.Write);

            fps.Base.Save(ostream);
            ostream.Close();

            stream.Close();

            cache.Dispose();
        }
Exemplo n.º 14
0
        public static void PatchChara(string charaPath, string patchDir, string outDir, string outMd5 = null, BackgroundWorker worker = null)
        {
            if (!File.Exists(charaPath))
            {
                throw new PatchingException("File not found: " + charaPath);
            }
            if (worker != null)
            {
                worker.ReportProgress(0, "Confirming source file...");
            }
            // if patched file exists and matches, exit early
            string outPath = Path.Combine(outDir, "chara.svo");

            try { CompareMd5Output(outPath, outMd5); return; } catch (PatchingException) { } catch (FileNotFoundException) { }
            CompareMd5(charaPath, "38984a5656b7a2faac3a7e24c962607e");
            Logger.LogFileData(charaPath, "chara.svo");
            Logger.LogDirData(patchDir, "chara patches");

            if (worker != null)
            {
                worker.ReportProgress(0, "Extracting source file...");
            }
            string extractPath = svoExtractToTempDir(charaPath);

            if (worker != null)
            {
                worker.ReportProgress(0, "Patching files...");
            }

            foreach (var patchDirG in Directory.GetDirectories(patchDir))
            {
                string charaFilePath = Path.Combine(extractPath, Path.GetFileName(patchDirG) + ".DAT");
                string decompPath    = TempUtil.GetTempFileName();
                tlzcDecompress(charaFilePath, decompPath);
                string subDir = svoExtractToTempDir(decompPath);

                foreach (var patchDirH in Directory.GetDirectories(patchDirG))
                {
                    string subPath   = Path.Combine(subDir, Path.GetFileName(patchDirH));
                    string subSubDir = svoExtractToTempDir(subPath, true);

                    foreach (var patch in Util.DirectoryGetFilesWorkaround(patchDirH))
                    {
                        string toPatchCompressed = Path.Combine(subSubDir, Path.GetFileNameWithoutExtension(patch));
                        string toPatch           = TempUtil.GetTempFileName();
                        tlzcDecompress(toPatchCompressed, toPatch);

                        string patched = TempUtil.GetTempFileName();
                        XdeltaApply(toPatch, patched, patch);
                        File.Delete(toPatch);

                        tlzcCompress(patched, toPatchCompressed);
                        File.Delete(patched);
                    }

                    string newSubPath = TempUtil.GetTempFileName();
                    using (var fps4 = new FPS4(subPath)) {
                        fps4.Alignment = 0x80;
                        fps4.Pack(subSubDir, newSubPath);
                    }
                    File.Delete(subPath);
                    File.Move(newSubPath, subPath);
                    Util.DeleteDirectoryAggressive(subSubDir, true);
                }

                string newPath = TempUtil.GetTempFileName();
                using (var fps4 = new FPS4(decompPath)) {
                    fps4.Alignment = 0x80;
                    fps4.Pack(subDir, newPath);
                }
                tlzcCompress(newPath, charaFilePath);
                File.Delete(newPath);
                File.Delete(decompPath);
                Util.DeleteDirectoryAggressive(subDir, true);
            }

            // dice minigame textures
            {
                string EP_0670_010        = Path.Combine(extractPath, "EP_0670_010.DAT");
                string EP_0670_010decomp  = tlzcDecompressToTempFile(EP_0670_010);
                string EP_0670_010extract = svoExtractToTempDir(EP_0670_010decomp);
                {
                    string EP_0670_010e_0002        = Path.Combine(EP_0670_010extract, "0002");
                    string EP_0670_010e_0002extract = svoExtractToTempDir(EP_0670_010e_0002, true);
                    {
                        string EP_0670_010e_0002e_0005       = Path.Combine(EP_0670_010e_0002extract, "0005");
                        string EP_0670_010e_0002e_0005decomp = tlzcDecompressToTempFile(EP_0670_010e_0002e_0005);
                        BlockCopy(EP_0670_010e_0002e_0005decomp, 0x100, EP_0670_010e_0002e_0005decomp, 0x100100, 0x100000);
                        tlzcCompress(EP_0670_010e_0002e_0005decomp, EP_0670_010e_0002e_0005);
                        File.Delete(EP_0670_010e_0002e_0005decomp);

                        string EP_0670_010e_0002e_0006       = Path.Combine(EP_0670_010e_0002extract, "0006");
                        string EP_0670_010e_0002e_0006decomp = tlzcDecompressToTempFile(EP_0670_010e_0002e_0006);
                        BlockCopy(EP_0670_010e_0002e_0006decomp, 0x100, EP_0670_010e_0002e_0006decomp, 0x100100, 0x100000);
                        tlzcCompress(EP_0670_010e_0002e_0006decomp, EP_0670_010e_0002e_0006);
                        File.Delete(EP_0670_010e_0002e_0006decomp);
                    }
                    string EP_0670_010e_0002new = TempUtil.GetTempFileName();
                    using (var fps4 = new FPS4(EP_0670_010e_0002)) {
                        fps4.Alignment = 0x80;
                        fps4.Pack(EP_0670_010e_0002extract, EP_0670_010e_0002new);
                    }
                    File.Delete(EP_0670_010e_0002);
                    File.Move(EP_0670_010e_0002new, EP_0670_010e_0002);
                    Util.DeleteDirectoryAggressive(EP_0670_010e_0002extract, true);
                }
                string EP_0670_010new = TempUtil.GetTempFileName();
                using (var fps4 = new FPS4(EP_0670_010decomp)) {
                    fps4.Alignment = 0x80;
                    fps4.Pack(EP_0670_010extract, EP_0670_010new);
                }
                tlzcCompress(EP_0670_010new, EP_0670_010);
                File.Delete(EP_0670_010decomp);
                File.Delete(EP_0670_010new);
                Util.DeleteDirectoryAggressive(EP_0670_010extract, true);
            }

            // "and they were never heard from again" textures
            {
                string GAMEOVER        = Path.Combine(extractPath, "GAMEOVER.DAT");
                string GAMEOVERdecomp  = tlzcDecompressToTempFile(GAMEOVER);
                string GAMEOVERextract = svoExtractToTempDir(GAMEOVERdecomp);
                {
                    string GAMEOVERe_0002        = Path.Combine(GAMEOVERextract, "0002");
                    string GAMEOVERe_0002extract = svoExtractToTempDir(GAMEOVERe_0002, true);
                    {
                        string GAMEOVERe_0002e_0001       = Path.Combine(GAMEOVERe_0002extract, "0001");
                        string GAMEOVERe_0002e_0001decomp = tlzcDecompressToTempFile(GAMEOVERe_0002e_0001);
                        BlockCopy(GAMEOVERe_0002e_0001decomp, 0x55D80, GAMEOVERe_0002e_0001decomp, 0xD80, 0x55000);
                        BlockCopy(GAMEOVERe_0002e_0001decomp, 0x55D80, GAMEOVERe_0002e_0001decomp, 0xAAD80, 0x55000);
                        tlzcCompress(GAMEOVERe_0002e_0001decomp, GAMEOVERe_0002e_0001);
                        File.Delete(GAMEOVERe_0002e_0001decomp);
                    }
                    string GAMEOVERe_0002new = TempUtil.GetTempFileName();
                    using (var fps4 = new FPS4(GAMEOVERe_0002)) {
                        fps4.Alignment = 0x80;
                        fps4.Pack(GAMEOVERe_0002extract, GAMEOVERe_0002new);
                    }
                    File.Delete(GAMEOVERe_0002);
                    File.Move(GAMEOVERe_0002new, GAMEOVERe_0002);
                    Util.DeleteDirectoryAggressive(GAMEOVERe_0002extract, true);
                }
                string GAMEOVERnew = TempUtil.GetTempFileName();
                using (var fps4 = new FPS4(GAMEOVERdecomp)) {
                    fps4.Alignment = 0x80;
                    fps4.Pack(GAMEOVERextract, GAMEOVERnew);
                }
                tlzcCompress(GAMEOVERnew, GAMEOVER);
                File.Delete(GAMEOVERdecomp);
                File.Delete(GAMEOVERnew);
                Util.DeleteDirectoryAggressive(GAMEOVERextract, true);
            }

            // more dice minigame textures why are there so many copies of those
            {
                string POR_C        = Path.Combine(extractPath, "POR_C.DAT");
                string POR_Cdecomp  = tlzcDecompressToTempFile(POR_C);
                string POR_Cextract = svoExtractToTempDir(POR_Cdecomp, true);
                {
                    string POR_Ce_0002        = Path.Combine(POR_Cextract, "0002");
                    string POR_Ce_0002extract = svoExtractToTempDir(POR_Ce_0002, true);
                    {
                        string POR_Ce_0002e_0026       = Path.Combine(POR_Ce_0002extract, "0026");
                        string POR_Ce_0002e_0026decomp = tlzcDecompressToTempFile(POR_Ce_0002e_0026);
                        BlockCopy(POR_Ce_0002e_0026decomp, 0x100, POR_Ce_0002e_0026decomp, 0x100100, 0x100000);
                        tlzcCompress(POR_Ce_0002e_0026decomp, POR_Ce_0002e_0026);
                        File.Delete(POR_Ce_0002e_0026decomp);

                        string POR_Ce_0002e_0027       = Path.Combine(POR_Ce_0002extract, "0027");
                        string POR_Ce_0002e_0027decomp = tlzcDecompressToTempFile(POR_Ce_0002e_0027);
                        BlockCopy(POR_Ce_0002e_0027decomp, 0x100, POR_Ce_0002e_0027decomp, 0x100100, 0x100000);
                        tlzcCompress(POR_Ce_0002e_0027decomp, POR_Ce_0002e_0027);
                        File.Delete(POR_Ce_0002e_0027decomp);
                    }
                    string POR_Ce_0002new = TempUtil.GetTempFileName();
                    using (var fps4 = new FPS4(POR_Ce_0002)) {
                        fps4.Alignment = 0x80;
                        fps4.Pack(POR_Ce_0002extract, POR_Ce_0002new);
                    }
                    File.Delete(POR_Ce_0002);
                    File.Move(POR_Ce_0002new, POR_Ce_0002);
                    Util.DeleteDirectoryAggressive(POR_Ce_0002extract, true);
                }
                string POR_Cnew = TempUtil.GetTempFileName();
                using (var fps4 = new FPS4(POR_Cdecomp)) {
                    fps4.Alignment = 0x80;
                    fps4.Pack(POR_Cextract, POR_Cnew);
                }
                tlzcCompress(POR_Cnew, POR_C);
                File.Delete(POR_Cdecomp);
                File.Delete(POR_Cnew);
                Util.DeleteDirectoryAggressive(POR_Cextract, true);
            }

            // extract yuri towel costume into its own archive
            {
                string EP_1320_060        = Path.Combine(extractPath, "EP_1320_060.DAT");
                string EP_1320_060decomp  = tlzcDecompressToTempFile(EP_1320_060);
                string EP_1320_060extract = svoExtractToTempDir(EP_1320_060decomp);
                {
                    string EP_1320_060e_0002        = Path.Combine(EP_1320_060extract, "0002");
                    string EP_1320_060e_0002extract = svoExtractToTempDir(EP_1320_060e_0002);
                    {
                        foreach (string file in Util.DirectoryGetFilesWorkaround(EP_1320_060e_0002extract))
                        {
                            if (!file.EndsWith("4"))
                            {
                                File.Delete(file);
                            }
                        }

                        string EP_1320_060e_0002new = Path.Combine(EP_1320_060extract, "0002.new");
                        using (var fps4 = new FPS4()) {
                            fps4.Alignment      = 0x80;
                            fps4.ContentBitmask = 0x0047;
                            fps4.Pack(Util.DirectoryGetFilesWorkaround(EP_1320_060e_0002extract), EP_1320_060e_0002new, "n");
                        }
                        File.Delete(EP_1320_060e_0002);
                        File.Move(EP_1320_060e_0002new, EP_1320_060e_0002);
                        Util.DeleteDirectoryAggressive(EP_1320_060e_0002extract, true);
                    }

                    File.Delete(Path.Combine(EP_1320_060extract, "0001"));
                    File.Copy(Path.Combine(EP_1320_060extract, "0003"), Path.Combine(EP_1320_060extract, "0001"));

                    string EP_1320_060e_0000        = Path.Combine(EP_1320_060extract, "0000");
                    string EP_1320_060e_0000extract = Path.Combine(EP_1320_060extract, "0000.ext");
                    if (Directory.Exists(EP_1320_060e_0000extract))
                    {
                        Util.DeleteDirectoryAggressive(EP_1320_060e_0000extract, true);
                    }
                    Directory.CreateDirectory(EP_1320_060e_0000extract);
                    using (var fps4 = new FPS4(EP_1320_060e_0000)) {
                        fps4.Extract(EP_1320_060e_0000extract);
                    }
                    {
                        foreach (string dir in Directory.GetDirectories(EP_1320_060e_0000extract))
                        {
                            if (!Path.GetFileName(dir).StartsWith("P"))
                            {
                                Util.DeleteDirectoryAggressive(dir, true);
                            }
                        }
                        foreach (string dir in Directory.GetDirectories(Directory.GetDirectories(EP_1320_060e_0000extract).First()))
                        {
                            string dirname = Path.GetFileName(dir);
                            if (!(dirname.StartsWith("Y") || dirname.EndsWith("2")))
                            {
                                Util.DeleteDirectoryAggressive(dir, true);
                            }
                        }
                        foreach (string dir in Directory.GetDirectories(Directory.GetDirectories(Directory.GetDirectories(EP_1320_060e_0000extract).First()).First()))
                        {
                            string dirname = Path.GetFileName(dir);
                            if (!dir.EndsWith("M"))
                            {
                                Util.DeleteDirectoryAggressive(dir, true);
                            }
                        }

                        string EP_1320_060e_0000new = Path.Combine(EP_1320_060extract, "0000.new");
                        using (var fps4 = new FPS4()) {
                            fps4.Alignment      = 0x80;
                            fps4.ContentBitmask = 0x0047;
                            var files = Util.DirectoryGetFilesWorkaround(EP_1320_060e_0000extract, "*", System.IO.SearchOption.AllDirectories).OrderBy(x => x.Split('.').Last()).ToArray();
                            fps4.Pack(files, EP_1320_060e_0000new, "p");
                        }
                        File.Delete(EP_1320_060e_0000);
                        File.Move(EP_1320_060e_0000new, EP_1320_060e_0000);
                        Util.DeleteDirectoryAggressive(EP_1320_060e_0000extract, true);
                    }
                }
                string YUR_C201new = Path.Combine(extractPath, "YUR_C201.DAT.dec.new");
                using (var fps4 = new FPS4()) {
                    fps4.Alignment      = 0x80;
                    fps4.ContentBitmask = 0x0007;
                    fps4.ArchiveName    = "YUR_C201";
                    fps4.Pack(Util.DirectoryGetFilesWorkaround(EP_1320_060extract), YUR_C201new);
                }
                Util.DeleteDirectoryAggressive(EP_1320_060extract, true);

                tlzcCompress(YUR_C201new, Path.Combine(extractPath, "YUR_C201.DAT"));

                File.Delete(EP_1320_060decomp);
                File.Delete(YUR_C201new);
            }

            if (worker != null)
            {
                worker.ReportProgress(100, "Packing modified file...");
            }
            Logger.LogDirData(extractPath, "chara dir patched");
            using (var fps4 = new FPS4()) {
                using (var oldfps4 = new FPS4(charaPath)) {
                    fps4.Unknown2    = oldfps4.Unknown2;
                    fps4.ArchiveName = oldfps4.ArchiveName;
                }
                fps4.Alignment = 0x800;
                fps4.Pack(extractPath, outPath);
            }
            Logger.LogFileData(outPath, "chara.svo patched");
            Util.DeleteDirectoryAggressive(extractPath, true);

            if (outMd5 != null)
            {
                CompareMd5Output(outPath, outMd5);
            }
        }
Exemplo n.º 15
0
        protected void HandleEntry(Regex SelectAll, Func <String, String, String> ReplaceSuffixName, FPS4.Entry EnglishEntry)
        {
            //Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
            using (EnglishEntry)
            {
                //Console.WriteLine("[1]");
                var BaseName    = SelectAll.Match(EnglishEntry.Name).Groups[1].Value;
                var SpanishName = ReplaceSuffixName(EnglishEntry.Name, "ES");
                Console.WriteLine("{0} : {1}", SpanishName, Thread.CurrentThread.ManagedThreadId);

                var ACMEFiles = ACME1.FilesByIndex.Where(Item => Item.Name.Contains(BaseName));
                if (ACMEFiles.Count() == 1)
                {
                    //Console.WriteLine("[2]");

                    var EsTempFile = TestOutputFolder + @"\" + SpanishName;

#if REUSE_PAK
                    if (!File.Exists(EsTempFile))
#endif
                    {
                        using (var CompressedSkitPAKStream = File.Open(EsTempFile, FileMode.Create))
                        {
                            //Console.WriteLine("[3]");
                            var ACMEFile = ACMEFiles.ElementAt(0);
                            //Console.WriteLine(SpanishName);
                            using (var SkitPAK = new FPS4(TalesCompression.DecompressStream(EnglishEntry.Open())))
                                using (var chtx = new TO8CHTX(SkitPAK[3].Open()))
                                {
                                    //Console.WriteLine("[4]");
                                    try
                                    {
                                        chtx.TranslateWithAcmeFile(ACMEFile);
                                    }
                                    catch (Exception Exception)
                                    {
                                        Console.Error.WriteLine(Exception);
                                        Console.ReadKey();
                                    }

                                    //Console.WriteLine("[5]");
                                    using (var NewChtxStream = new MemoryStream())
                                        using (var SkitPAKStream = new MemoryStream())
                                        {
                                            chtx.Save(NewChtxStream);
                                            SkitPAK[3].SetStream(NewChtxStream);

                                            //Console.WriteLine("[6]");
                                            SkitPAK.Save(SkitPAKStream);

                                            TalesCompression.EncodeFile(SkitPAKStream, CompressedSkitPAKStream);
                                        }
                                }
                        }
                    }
                    var SpanishEntry = PAK.CreateEntry(SpanishName, File.Open(EsTempFile, FileMode.Open));
                }
                else
                {
                    Console.WriteLine("WARNING. Untranslated Skit: ACMEFiles.Count() : {0} : {1}", ACMEFiles.Count(), BaseName);
                    var SpanishEntry = PAK.CreateEntry(SpanishName, EnglishEntry.Open());
                }
            }
        }
Exemplo n.º 16
0
        public static Stream ProcessTexture(string name, DuplicatableStream ustream, DuplicatableStream wstream)
        {
            FPS4 w    = new FPS4(wstream.Duplicate());
            TXM  wtxm = new TXM(w.GetChildByIndex(0).AsFile.DataStream.Duplicate());
            TXV  wtxv = new TXV(wtxm, w.GetChildByIndex(1).AsFile.DataStream.Duplicate(), false);
            FPS4 u    = new FPS4(ustream.Duplicate());
            TXM  utxm = new TXM(u.GetChildByIndex(0).AsFile.DataStream.Duplicate());
            TXV  utxv = new TXV(utxm, u.GetChildByIndex(1).AsFile.DataStream.Duplicate(), false);
            List <TexConvRules> convs = new List <TexConvRules>();

            if (name == "rootR.cpk/mg/tex/karuta.tex")
            {
                convs.Add(new TexConvRules()
                {
                    WTexId = 2, UTexId = 1, Method = TexConvMethod.Delegate, Delegate = (wtex, utex) => DoKarutaHalfAndHalf(wtex, utex, 82, 134, 294)
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 4, UTexId = 3, Method = TexConvMethod.Delegate, Delegate = (wtex, utex) => DoKarutaHalfAndHalf(wtex, utex, 86, 134, 294)
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 7, UTexId = 7, Method = TexConvMethod.DownscaleTwoThirds
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 13, UTexId = 13, Method = TexConvMethod.Delegate, Delegate = (wtex, utex) => DoKaruta13(wtex, utex)
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 17, UTexId = 17, Method = TexConvMethod.DownscaleTwoThirds
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 22, UTexId = 23, Method = TexConvMethod.Delegate, Delegate = (wtex, utex) => DownscaleTwoThirds(CropExpandCanvas(utex, 2, -2, (uint)(utex.Width + 3), (uint)(utex.Height - 3)))
                });
            }
            else if (name == "rootR.cpk/mnu/tex/main.tex")
            {
                convs.Add(new TexConvRules()
                {
                    WTexId = 110, UTexId = 61, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 111, UTexId = 62, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 112, UTexId = 63, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 113, UTexId = 64, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 114, UTexId = 65, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 115, UTexId = 66, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 116, UTexId = 67, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 117, UTexId = 68, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 118, UTexId = 69, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 119, UTexId = 70, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 124, UTexId = 75, Method = TexConvMethod.Downscale2x
                });
            }
            else if (name == "rootR.cpk/mnu/tex/shop.tex")
            {
                convs.Add(new TexConvRules()
                {
                    WTexId = 1, UTexId = 1, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 2, UTexId = 2, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 3, UTexId = 3, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 4, UTexId = 4, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 5, UTexId = 5, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 6, UTexId = 6, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 7, UTexId = 7, Method = TexConvMethod.Downscale2x
                });
            }
            else if (name == "rootR.cpk/mnu/tex/skill.tex")
            {
                convs.Add(new TexConvRules()
                {
                    WTexId = 0, UTexId = 0, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 1, UTexId = 1, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 2, UTexId = 2, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 3, UTexId = 3, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 4, UTexId = 4, Method = TexConvMethod.Downscale2x
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 5, UTexId = 5, Method = TexConvMethod.Downscale2x
                });
            }
            else if (name == "rootR.cpk/mnu/tex/snd_test.tex")
            {
                convs.Add(new TexConvRules()
                {
                    WTexId = 1, UTexId = 1, Method = TexConvMethod.Downscale2x
                });
            }
            else if (name == "rootR.cpk/SysSub/JA/TitleTexture.tex")
            {
                convs.Add(new TexConvRules()
                {
                    WTexId = 1, UTexId = 1, Method = TexConvMethod.CropExpandCanvas
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 2, UTexId = 4, Method = TexConvMethod.CropExpandCanvas
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 3, UTexId = 6, Method = TexConvMethod.CropExpandCanvas
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 4, UTexId = 8, Method = TexConvMethod.CropExpandCanvas
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 6, UTexId = 12, Method = TexConvMethod.CropExpandCanvas
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 7, UTexId = 14, Method = TexConvMethod.CropExpandCanvas
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 8, UTexId = 16, Method = TexConvMethod.CropExpandCanvas
                });
            }
            else if (name.EndsWith(".CLG"))
            {
                convs.Add(new TexConvRules()
                {
                    WTexId = 0, UTexId = 0, Method = TexConvMethod.DownscaleTwoThirds
                });
                convs.Add(new TexConvRules()
                {
                    WTexId = 1, UTexId = 1, Method = TexConvMethod.Clear
                });
            }

            MemoryStream s = wstream.Duplicate().CopyToMemory();

            s.Position = 0;
            foreach (TexConvRules c in convs)
            {
                var wm = wtxm.TXMRegulars[c.WTexId];
                var um = utxm.TXMRegulars[c.UTexId];
                var wv = wtxv.textures.Where(x => x.TXM == wm).First();
                var uv = utxv.textures.Where(x => x.TXM == um).First();
                System.Drawing.Bitmap newImage = null;
                switch (c.Method)
                {
                case TexConvMethod.Downscale2x: {
                    newImage = FontProcessing.DownscaleInteger(uv.GetBitmaps()[0], 2);
                }
                break;

                case TexConvMethod.DownscaleTwoThirds: {
                    newImage = DownscaleTwoThirds(uv.GetBitmaps()[0]);
                }
                break;

                case TexConvMethod.CropExpandCanvas: {
                    newImage = DoCropExpandCanvas(uv.GetBitmaps()[0], wm.Width, wm.Height);
                }
                break;

                case TexConvMethod.Clear: {
                    newImage = new Bitmap(wv.GetBitmaps()[0]);
                    for (int y = 0; y < newImage.Height; ++y)
                    {
                        for (int x = 0; x < newImage.Width; ++x)
                        {
                            newImage.SetPixel(x, y, Color.FromArgb(0, 0, 0, 0));
                        }
                    }
                }
                break;

                case TexConvMethod.Delegate: {
                    newImage = c.Delegate(wv.GetBitmaps()[0], uv.GetBitmaps()[0]);
                }
                break;

                default: {
                    throw new Exception("don't know how to convert " + uv.TXM.Name);
                }
                }
                if (newImage != null)
                {
                    HyoutaTools.Util.Assert(newImage.Width == wm.Width);
                    HyoutaTools.Util.Assert(newImage.Height == wm.Height);
                    if (wm.Format == HyoutaTools.Tales.Vesperia.Texture.TextureFormat.Indexed8Bits_RGB5A3)
                    {
                        ChopBitsRGB5A3(newImage);
                        var palette = GeneratePalette256(newImage);

                        s.Position = w.Files[1].Location.Value + wm.TxvLocation;
                        foreach (var loc in new HyoutaTools.Textures.PixelOrderIterators.TiledPixelOrderIterator(newImage.Width, newImage.Height, 8, 4))
                        {
                            int cval = 0;
                            if (loc.X < newImage.Width && loc.Y < newImage.Height)
                            {
                                cval = palette.lookup[newImage.GetPixel(loc.X, loc.Y)];
                            }
                            s.WriteByte((byte)cval);
                        }

                        for (int ci = 0; ci < 256; ++ci)
                        {
                            ushort cval = 0;
                            if (ci < palette.colors.Count)
                            {
                                cval = HyoutaTools.Textures.ColorFetchingIterators.ColorFetcherRGB5A3.ColorToRGB5A3(palette.colors[ci]);
                            }
                            s.WriteUInt16(cval.ToEndian(EndianUtils.Endianness.BigEndian));
                        }
                    }
                    else if (wm.Format == HyoutaTools.Tales.Vesperia.Texture.TextureFormat.GamecubeRGBA8)
                    {
                        s.Position = w.Files[1].Location.Value + wm.TxvLocation;
                        byte[] tmpb = new byte[0x40];
                        int    tmpp = 0;
                        foreach (var loc in new HyoutaTools.Textures.PixelOrderIterators.TiledPixelOrderIterator(newImage.Width, newImage.Height, 4, 4))
                        {
                            Color col = newImage.GetPixel(loc.X, loc.Y);
                            tmpb[tmpp * 2 + 0]        = col.A;
                            tmpb[tmpp * 2 + 1]        = col.R;
                            tmpb[tmpp * 2 + 0 + 0x20] = col.G;
                            tmpb[tmpp * 2 + 1 + 0x20] = col.B;
                            ++tmpp;
                            if (tmpp == 16)
                            {
                                tmpp = 0;
                                s.Write(tmpb);
                            }
                        }
                        if (tmpp != 0)
                        {
                            throw new Exception("Unexpected tile size for " + wm.Name);
                        }
                    }
                    else
                    {
                        Console.WriteLine("don't know how to encode into " + wm.Format);
                    }
                }
            }

            s.Position = 0;
            return(s);
        }
Exemplo n.º 17
0
        private static void GenerateUndubRoot(string datadir, string voicedir, string outdir, UndubVersion undubVersion)
        {
            Console.WriteLine(string.Format("processing {0}", "rootR.cpk"));
            var    datastream  = new DuplicatableFileStream(Path.Combine(datadir, "rootR.cpk"));
            var    voicestream = new DuplicatableFileStream(Path.Combine(voicedir, "rootR.cpk"));
            var    datacpk     = new HyoutaTools.Tales.CPK.CpkContainer(datastream.Duplicate());
            var    voicecpk    = new HyoutaTools.Tales.CPK.CpkContainer(voicestream);
            string outfile     = Path.Combine(outdir, "rootR.cpk");
            var    builder     = new HyoutaTools.Tales.CPK.CpkBuilder(datastream.Duplicate());

            // audio containers: we can direct-copy these, no need to un/repack
            foreach (string name in new string[] { "RTS.nub", "VOBTL.nub", "VOBTLETC.nub", "VOCHT.nub", "VOSCE01.nub", "VOSCE02.nub", "VOSCE03.nub", "VOSCE04.nub", "VOSCE05.nub", "VOSCE06.nub", "VOSCE07.nub", "VOSCE08.nub", "VOSCE09.nub", "VOSCE15.nub", "VOSCE16.nub" })
            {
                string subdir  = "snd/strpck";
                string subpath = subdir + "/" + name;
                Console.WriteLine(string.Format("injecting {0}", subpath));
                var subfile = builder.Files.Where(x => x.Directory == subdir && x.Name == name).First();
                ReplaceFile(subfile, voicecpk.GetChildByName(subpath).AsFile.DataStream.Duplicate().CopyToByteArrayStreamAndDispose());
            }

            // skits: for all of these unpack them (FPS4 containers), copy over file with index 1, repack
            // some of them are mistimed now because of altered timing for english skits, this could be refined...
            for (long i = 0; i < datacpk.toc_entries; ++i)
            {
                var entry = datacpk.GetEntryByIndex(i);
                if (entry != null && entry.dir_name == "chat/chd" && entry.file_name.EndsWith(".chd") && entry.file_name != "debug_02.chd")
                {
                    // for EU undub also exclude CHT_PR*.chd because those files are not on the EU disc (they look unused on US too...)
                    if (!(undubVersion == UndubVersion.JpVoicesToEu && entry.file_name.StartsWith("CHT_PR")))
                    {
                        string subpath = entry.dir_name + "/" + entry.file_name;
                        Console.WriteLine(string.Format("injecting {0}", subpath));
                        var skitstreamen = datacpk.GetChildByIndex(i).AsFile.DataStream;
                        var skitstreamjp = voicecpk.GetChildByName(subpath).AsFile.DataStream;
                        var fps4en       = new FPS4(skitstreamen);
                        var fps4jp       = new FPS4(skitstreamjp);

                        List <PackFileInfo> packFileInfos = new List <PackFileInfo>(fps4en.Files.Count - 1);
                        for (int j = 0; j < fps4en.Files.Count - 1; ++j)
                        {
                            var pf = new PackFileInfo();
                            pf.Name = fps4en.Files[j].FileName;
                            if (j == 1)
                            {
                                pf.DataStream = fps4jp.GetChildByIndex(j).AsFile.DataStream.Duplicate();
                            }
                            else
                            {
                                pf.DataStream = fps4en.GetChildByIndex(j).AsFile.DataStream.Duplicate();
                            }
                            pf.Length = pf.DataStream.Length;
                            packFileInfos.Add(pf);
                        }
                        packFileInfos = FPS4.DetectDuplicates(packFileInfos);
                        MemoryStream newfps4stream = new MemoryStream();
                        FPS4.Pack(packFileInfos, newfps4stream, fps4en.ContentBitmask, EndianUtils.Endianness.BigEndian, fps4en.Unknown2, null, fps4en.ArchiveName, fps4en.FirstFileStart, 0x20);
                        newfps4stream.Position = 0;

                        var subfile = builder.Files.Where(x => x.Directory == entry.dir_name && x.Name == entry.file_name).First();
                        ReplaceFile(subfile, newfps4stream.CopyToByteArrayStreamAndDispose(), true);
                    }
                }
            }

            // post-battle skits/quotes
            for (long i = 0; i < datacpk.toc_entries; ++i)
            {
                var entry = datacpk.GetEntryByIndex(i);
                if (entry != null && entry.dir_name == "btl/acf" && (
                        (entry.file_name.StartsWith("skt") && entry.file_name.EndsWith(".acf") && entry.file_name != "skt000.acf") ||
                        (entry.file_name.StartsWith("vav") && entry.file_name.EndsWith(".acf") && entry.file_name != "vav000.acf")
                        ))
                {
                    string subpath = entry.dir_name + "/" + entry.file_name;
                    Console.WriteLine(string.Format("injecting {0}", subpath));
                    var subfile = builder.Files.Where(x => x.Directory == entry.dir_name && x.Name == entry.file_name).First();
                    ReplaceFile(subfile, voicecpk.GetChildByName(subpath).AsFile.DataStream.Duplicate().CopyToByteArrayStreamAndDispose());
                }
            }

            CreateDirectory(outdir);
            WriteCpk(outfile, builder);
        }
Exemplo n.º 18
0
        public static void PatchBtl(string btlPath, string patchDir, string outDir, string outMd5 = null, BackgroundWorker worker = null)
        {
            if (!File.Exists(btlPath))
            {
                throw new PatchingException("File not found: " + btlPath);
            }
            if (worker != null)
            {
                worker.ReportProgress(0, "Confirming source file...");
            }
            // if patched file exists and matches, exit early
            string outPath = Path.Combine(outDir, "btl.svo");

            try { CompareMd5Output(outPath, outMd5); return; } catch (PatchingException) { } catch (FileNotFoundException) { }
            CompareMd5(btlPath, "37bed259717dd27e5145d8899e7c36d9");
            Logger.LogFileData(btlPath, "btl.svo");
            Logger.LogDirData(patchDir, "btl patches");

            // extract
            if (worker != null)
            {
                worker.ReportProgress(0, "Extracting source file...");
            }
            string extractPath = svoExtractToTempDir(btlPath);
            string btlPackPath = svoExtractToTempDir(Path.Combine(extractPath, "BTL_PACK.DAT"));
            string file3Path   = svoExtractToTempDir(Path.Combine(btlPackPath, "0003"), nometa: true);

            // patch
            int i     = 0;
            var files = Util.DirectoryGetFilesWorkaround(patchDir);

            foreach (string patch in files)
            {
                if (worker != null)
                {
                    worker.ReportProgress((i / files.Length) * 100, "Patching file " + (i + 1) + " of " + files.Length + "...");
                }
                string fileName = Path.GetFileNameWithoutExtension(patch);

                string sourcePath       = Path.Combine(file3Path, "0" + fileName);
                string decompressedPath = tlzcDecompressToTempFile(sourcePath);
                string patchedPath      = TempUtil.GetTempFileName();
                XdeltaApply(decompressedPath, patchedPath, patch);
                tlzcCompress(patchedPath, sourcePath);

                System.IO.File.Delete(decompressedPath);
                System.IO.File.Delete(patchedPath);

                ++i;
            }

            // pack
            if (worker != null)
            {
                worker.ReportProgress(100, "Packing modified file...");
            }
            Logger.LogDirData(file3Path, "btl/btl_pack/3 dir patched");
            using (var fps4file3 = new FPS4(Path.Combine(btlPackPath, "0003"))) {
                fps4file3.Alignment = 0x80;
                fps4file3.Pack(file3Path, Path.Combine(btlPackPath, "0003.new"));
            }
            File.Delete(Path.Combine(btlPackPath, "0003"));
            File.Move(Path.Combine(btlPackPath, "0003.new"), Path.Combine(btlPackPath, "0003"));
            Util.DeleteDirectoryAggressive(file3Path, true);

            using (var fps4btlPack = new FPS4(Path.Combine(extractPath, "BTL_PACK.DAT"))) {
                fps4btlPack.Alignment = 0x80;
                fps4btlPack.Pack(btlPackPath, Path.Combine(extractPath, "BTL_PACK.DAT.new"));
            }
            File.Delete(Path.Combine(extractPath, "BTL_PACK.DAT"));
            File.Move(Path.Combine(extractPath, "BTL_PACK.DAT.new"), Path.Combine(extractPath, "BTL_PACK.DAT"));
            Util.DeleteDirectoryAggressive(btlPackPath, true);

            Logger.LogDirData(extractPath, "btl dir patched");
            using (var fps4btl = new FPS4(btlPath)) {
                fps4btl.Alignment = 0x800;
                fps4btl.Pack(extractPath, outPath);
            }
            Logger.LogFileData(outPath, "btl.svo patched");
            Util.DeleteDirectoryAggressive(extractPath, true);

            if (outMd5 != null)
            {
                CompareMd5Output(outPath, outMd5);
            }
        }
Exemplo n.º 19
0
        private void Handle1()
        {
            Patcher.TempFS.CreateDirectory("CHAT_ES", 0777, false);

            Patcher.Action("Translating Skits...", () =>
            {
                Patcher.ProgressHandler.AddProgressLevel("Traduciendo skits", OriginalChatSvo.Count(), () =>
                {
                    Patcher.ParallelForeach("Translating", OriginalChatSvo, (ChatSvoEntry) => ChatSvoEntry.Name, (ChatSvoEntry) =>
                    {
                        var Match = ChatSvoEntry.Name.RegexMatch(@"^(VC\d+B?)(UK)\.DAT$");
                        if (Match != null)
                        {
                            var CompleteFile = Match[0].Value;
                            var ChatId       = Match[1].Value;
                            var EsFile       = PreppendTempFile + ChatId + "ES.DAT";

                            Console.WriteLine("{0}...", ChatId);

                            if (!Patcher.TempFS.Exists(EsFile))
                            {
                                var Fps4 = new FPS4(TalesCompression.DecompressStream(OriginalChatSvo[CompleteFile].Open()));
                                {
                                    var Chtx = new TO8CHTX();
                                    Chtx.Load(Fps4["3"].Open());
                                    // Translate
                                    {
                                        foreach (var Entry in Patcher.EntriesByRoom["skits/" + ChatId].Values)
                                        {
                                            int TextId = int.Parse(Entry.text_id) - 1;
                                            if (TextId >= 0)
                                            {
                                                //Chtx[TextId].Title = "";
                                                //Chtx[TextId].Title = TextProcessor.Instance.ProcessAndDetectPitfalls(Chtx[TextId].Title, Entry.texts.es[0].TrimEnd(' ', '\t', '\n', '\r', '.'));
                                                //Chtx[TextId].Title = TextProcessor.Instance.ProcessAndDetectPitfalls(Chtx[TextId].Title, Entry.texts.es[0]);
                                                Chtx[TextId].Title          = "";
                                                Chtx[TextId].TextOriginal   = "";
                                                Chtx[TextId].TextTranslated = TextProcessor.Instance.ProcessAndDetectPitfalls(Chtx[TextId].TextTranslated, Entry.texts.es[1]);
                                            }
                                        }
                                    }
                                    //ChtxStream.SetLength(0);
                                    var ChtxStream = new MemoryStream();
                                    Chtx.SaveTo(ChtxStream);
                                    ChtxStream.Position = 0;
                                    Fps4["3"].SetStream(ChtxStream);
                                }
                                Patcher.TempFS.WriteAllBytes(EsFile, TalesCompression.CreateFromVersion(Patcher.CompressionVersion, Patcher.CompressionFallback).EncodeBytes(Fps4.Save(false).ToArray()));
                                Console.WriteLine("{0}...Ok", ChatId);
                            }
                            else
                            {
                                Console.WriteLine("{0}...Exists", ChatId);
                            }
                        }

                        Patcher.ProgressHandler.IncrementLevelProgress();
                    });
                });
            });
        }
Exemplo n.º 20
0
 public void Initialize()
 {
     fps4 = new FPS4();
 }
Exemplo n.º 21
0
        public static int Execute(List <string> args)
        {
            bool gamedirmode = args.Count == 3 || args.Count == 4;
            bool manualmode  = args.Count == 9;

            if (!gamedirmode && !manualmode)
            {
                System.Windows.Forms.MessageBox.Show(
                    "Requires arguments:\n\n" +
                    "  For automatically fetching files from game directory (point at folder containing item.svo):\n" +
                    "    Version Locale GameDirectory [STRING_DIC.SO]\n" +
                    "  STRING_DIC.SO can be overridden to select a different language file.\n" +
                    "\n" +
                    "  For manually providing files:\n" +
                    "    Version Locale ITEM.DAT STRING_DIC.SO T8BTSK T8BTEMST COOKDAT WRLDDAT ITEMSORT.DAT\n" +
                    "\n" +
                    "'Version' should be one of: 360, 360EU, PS3, PC\n" +
                    "'Locale' should be 1 for the 1st language in the given STRING_DIC, or 2 for the second"
                    );
                return(-1);
            }

            GameVersion?version = null;

            EndianUtils.Endianness     endian   = EndianUtils.Endianness.BigEndian;
            BitUtils.Bitness           bits     = BitUtils.Bitness.B32;
            TextUtils.GameTextEncoding encoding = TextUtils.GameTextEncoding.ShiftJIS;
            switch (args[0].ToUpperInvariant())
            {
            case "360":
                version = GameVersion.X360_US;
                break;

            case "360EU":
                version  = GameVersion.X360_EU;
                encoding = TextUtils.GameTextEncoding.UTF8;
                break;

            case "PS3":
                version = GameVersion.PS3;
                break;

            case "PC":
                version  = GameVersion.PC;
                endian   = EndianUtils.Endianness.LittleEndian;
                bits     = BitUtils.Bitness.B64;
                encoding = TextUtils.GameTextEncoding.UTF8;
                break;
            }
            int locale = 0;

            if (args[1] == "1")
            {
                locale = 1;
            }
            else if (args[1] == "2")
            {
                locale = 2;
            }

            if (version == null || locale == 0)
            {
                Console.WriteLine("First parameter must indicate game version, second parameter must indicate locale!");
                return(-1);
            }

            DuplicatableStream itemDatStream;
            DuplicatableStream itemSortStream;
            DuplicatableStream stringDicStream;
            DuplicatableStream skillsStream;
            DuplicatableStream enemiesStream;
            DuplicatableStream cookdatStream;
            DuplicatableStream locationsStream;

            if (manualmode)
            {
                itemDatStream   = new DuplicatableFileStream(args[2]).CopyToByteArrayStreamAndDispose();
                itemSortStream  = new DuplicatableFileStream(args[8]).CopyToByteArrayStreamAndDispose();
                stringDicStream = new DuplicatableFileStream(args[3]).CopyToByteArrayStreamAndDispose();
                skillsStream    = new DuplicatableFileStream(args[4]).CopyToByteArrayStreamAndDispose();
                enemiesStream   = new DuplicatableFileStream(args[5]).CopyToByteArrayStreamAndDispose();
                cookdatStream   = new DuplicatableFileStream(args[6]).CopyToByteArrayStreamAndDispose();
                locationsStream = new DuplicatableFileStream(args[7]).CopyToByteArrayStreamAndDispose();
            }
            else
            {
                bool hasCooksvo = VesperiaUtil.Is360(version.Value);

                using (var itemsvo = new FPS4(Path.Combine(args[2], "item.svo"))) {
                    itemDatStream  = itemsvo.GetChildByName("ITEM.DAT").AsFile.DataStream.CopyToByteArrayStreamAndDispose();
                    itemSortStream = itemsvo.GetChildByName("ITEMSORT.DAT").AsFile.DataStream.CopyToByteArrayStreamAndDispose();
                }
                using (var menusvo = new FPS4(Path.Combine(args[2], "menu.svo"))) {
                    if (!hasCooksvo)
                    {
                        cookdatStream = menusvo.GetChildByName("COOKDATA.BIN").AsFile.DataStream.CopyToByteArrayStreamAndDispose();
                    }
                    else
                    {
                        using (var cooksvo = new FPS4(Path.Combine(args[2], "cook.svo"))) {
                            cookdatStream = cooksvo.GetChildByName("COOKDATA.BIN").AsFile.DataStream.CopyToByteArrayStreamAndDispose();
                        }
                    }
                    locationsStream = menusvo.GetChildByName("WORLDDATA.BIN").AsFile.DataStream.CopyToByteArrayStreamAndDispose();
                }
                if (args.Count == 3)
                {
                    if (version == GameVersion.X360_EU)
                    {
                        stringDicStream = new DuplicatableFileStream(Path.Combine(args[2], "language", "string_dic_uk.so")).CopyToByteArrayStreamAndDispose();
                    }
                    else if (version == GameVersion.PC)
                    {
                        stringDicStream = new DuplicatableFileStream(Path.Combine(args[2], "language", "string_dic_ENG.so")).CopyToByteArrayStreamAndDispose();
                    }
                    else
                    {
                        using (var stringsvo = new FPS4(Path.Combine(args[2], "string.svo"))) {
                            stringDicStream = stringsvo.GetChildByName("STRING_DIC.SO").AsFile.DataStream.CopyToByteArrayStreamAndDispose();
                        }
                    }
                }
                else
                {
                    stringDicStream = new DuplicatableFileStream(args[3]).CopyToByteArrayStreamAndDispose();
                }
                using (var btlsvo = new FPS4(Path.Combine(args[2], "btl.svo"))) {
                    using (var btlpack = new FPS4(btlsvo.GetChildByName(version == GameVersion.X360_EU ? "BTL_PACK_UK.DAT" : "BTL_PACK.DAT").AsFile.DataStream)) {
                        using (var all = new FPS4(btlpack.GetChildByIndex(10).AsFile.DataStream)) {
                            skillsStream = all.GetChildByIndex(0).AsFile.DataStream.CopyToByteArrayStreamAndDispose();
                        }
                        using (var all = new FPS4(btlpack.GetChildByIndex(5).AsFile.DataStream)) {
                            enemiesStream = all.GetChildByIndex(0).AsFile.DataStream.CopyToByteArrayStreamAndDispose();
                        }
                    }
                }
            }


            HyoutaTools.Tales.Vesperia.ItemDat.ItemDat items = new HyoutaTools.Tales.Vesperia.ItemDat.ItemDat(itemDatStream, itemSortStream, EndianUtils.Endianness.BigEndian);

            TSSFile TSS;

            try {
                TSS = new TSSFile(stringDicStream, encoding, endian);
            } catch (System.IO.FileNotFoundException) {
                Console.WriteLine("Could not open STRING_DIC.SO, exiting.");
                return(-1);
            }

            HyoutaTools.Tales.Vesperia.T8BTSK.T8BTSK     skills    = new HyoutaTools.Tales.Vesperia.T8BTSK.T8BTSK(skillsStream, endian, bits);
            HyoutaTools.Tales.Vesperia.T8BTEMST.T8BTEMST enemies   = new HyoutaTools.Tales.Vesperia.T8BTEMST.T8BTEMST(enemiesStream, endian, bits);
            HyoutaTools.Tales.Vesperia.COOKDAT.COOKDAT   cookdat   = new HyoutaTools.Tales.Vesperia.COOKDAT.COOKDAT(cookdatStream, endian);
            HyoutaTools.Tales.Vesperia.WRLDDAT.WRLDDAT   locations = new HyoutaTools.Tales.Vesperia.WRLDDAT.WRLDDAT(locationsStream, endian);

            Console.WriteLine("Initializing GUI...");
            ItemForm itemForm = new ItemForm(version.Value, locale - 1, items, TSS, skills, enemies, cookdat, locations);

            itemForm.Show();
            return(0);
        }
Exemplo n.º 22
0
        static void Main(string[] args)
        {
            //var basename = @"C:\Juegos\fez\Content\Essentials.pak.d\fonts\zuish";
            //var basename = @"C:\Juegos\fez\Content\Essentials.pak.d\effects\basicposteffect";
            //var basename = @"C:\Juegos\fez\Content\Other.pak.d\background planes\qr_crypt";

            //DecodeImage(@"C:\Juegos\fez\Content\Other.pak.d\art objects\menu_cube");
            //Environment.Exit(0);

            //var Path = @"C:\Juegos\fez\Content\";
            var Path = @"C:\Juegos\fez\Content\Other.pak.d\art objects";

            foreach (var filename in Directory.EnumerateFiles(Path, "*", SearchOption.AllDirectories))
            {
                Console.WriteLine("{0}...", filename);
                try
                {
                    DecodeImage(filename);
                }
                catch (Exception Exception)
                {
                    //Console.WriteLine(Exception);
                }
            }


            //BE 5A 00 00
            //93 AA 04 00

            // 0x5ABE
            // 0xAA93

            /*
             * var Out = new MemoryStream();
             * Lzx.Decompress(Stream, 0x5ABE, Out, 0xAA93);
             * Console.WriteLine(Out.Length);
             */

            Console.ReadKey();

#if false
            //var FilePath = @"I:\isos\360\Tales of Vesperia [PAL] [Multi3] [English] [Xbox360].iso";
            var FilePath    = @"C:\tov\tov_spa.iso";
            var Dvd9Xbox360 = new Dvd9Xbox360();

            using (var IsoStream = File.Open(FilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                Dvd9Xbox360.Load(IsoStream);

                using (var map_svo_stream = Dvd9Xbox360.RootEntry["/map.svo"].Open())
                {
                    var map_svo = new FPS4(map_svo_stream);

                    map_svo["SCENARIO.DAT"].ReplaceWithFile(@"c:\tov\language\scenario_uk.dat");
                }

                Dvd9Xbox360.RootEntry["/language/scenario_us.dat"].ReplaceWithFile(@"c:\tov\language\scenario_uk.dat");
                Dvd9Xbox360.RootEntry["/language/scenario_uk.dat"].ReplaceWithFile(@"c:\tov\language\scenario_uk.dat");
                Dvd9Xbox360.RootEntry["/language/string_dic_uk.so"].ReplaceWithFile(@"c:\tov\language\string_dic_uk.so");
                Dvd9Xbox360.RootEntry["/UI.svo"].ReplaceWithFile(@"c:\tov\ui.svo");
                Dvd9Xbox360.RootEntry["/chat.svo"].ReplaceWithFile(@"c:\tov\chat.svo");
            }

            Console.WriteLine("Done. Press any key to continue.");
            Console.ReadKey();

            return;

#if true
            var TranslateSkits = new TranslateSkits(@"c:\tov\chat.svo.bak", @"c:\tov\chat.svo", @"tov_skits.zip");
            //var TranslateSkits = new TranslateSkits();
            //TranslateSkits.Backup();
            TranslateSkits.Process();

            new UpdateFont().Process(@"c:\tov\UI.svo", "FONTTEX10.TXV.mod.png");

            /*
             * Console.WriteLine("Decoding...");
             * //var Fps4 = new FPS4(File.Open(@"F:\Isos\360\games\vesperia\UI.svo", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite));
             * var Fps4 = new FPS4(File.Open(@"J:\games\vesperia\UI.svo", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite));
             * using (var Out = Fps4["FONTTEX10.TXV"].Open())
             * {
             *      DXT5.SaveSwizzled(new Bitmap(Image.FromFile("../../../TestInput/FONTTEX10.TXV.mod.png")), Out);
             * }
             * Console.WriteLine("Ok");
             */

            /*
             * //var Bitmap = DXT5.LoadSwizzled(File.OpenRead("../../../TestInput/FONTTEX05.TXV.mod.TXV"), 2048, 2048);
             * using (var Out = File.OpenWrite("../../../Lol.txv"))
             * {
             *      DXT5.SaveSwizzled(new Bitmap(Image.FromFile("../../../TestInput/FONTTEX10.TXV.mod.png")), Out);
             * }
             */
            //Bitmap.Save("../../../Lol.png");
#else
            var TranslateSkits = new TranslateSkits();
            TranslateSkits.Backup();
            TranslateSkits.Process();

            /*
             * var FPS4 = new FPS4();
             * FPS4.Load(File.OpenRead(@"J:\games\vesperia\chat.svo"));
             *
             * Console.WriteLine(FPS4.Entries["VC980US.DAT"].CompressedStream.Length);
             *
             * FPS4.Entries["VC980US.DAT"].CompressedStream.CopyTo(
             *      File.OpenWrite(@"C:\projects\svn.tales-tra.com\csharp\TalesOfVesperiaUtils\TestInput\VC980US.DAT"),
             *      8 * 1024 * 1024
             * );
             */
#endif
#endif
            Console.WriteLine("Done. Press any key to continue.");
            Console.ReadKey();
        }
Exemplo n.º 23
0
 public FPS4FileSystem(Stream Stream)
 {
     this.FPS4 = new FPS4(Stream);
 }
Exemplo n.º 24
0
        protected void Expand(string FilePath)
        {
            if (FilePath.Contains('*') || FilePath.Contains('?'))
            {
                var BasePath  = Path.GetDirectoryName(FilePath);
                var Recursive = false;
                if (BasePath == "")
                {
                    BasePath = ".";
                }
                foreach (var FileName in Directory.EnumerateFiles(BasePath, Path.GetFileName(FilePath), Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
                {
                    Expand(FileName);
                }
                return;
            }


            var ListToExpand = new List <string>();

            //Console.WriteLine("Expanding '{0}'...", FilePath);

            using (var _FileStream = File.OpenRead(FilePath))
            {
                if (_FileStream.Length == 0)
                {
                    //Console.WriteLine("EMPTY: {0}", FilePath);
                    return;
                }
                var FileStream = DecompressIfCompressedStream(_FileStream);
                var MagicData  = FileStream.Slice().ReadBytesUpTo(0x100);

                if (false)
                {
                }
                else if (TO8SCEL.IsValid(MagicData))
                {
                    try
                    {
                        var To8Scel = new TO8SCEL(FileStream);
                        foreach (var Entry in To8Scel)
                        {
                            var EntryFilePath = FilePath + ".d/" + Entry.Index;
                            if (Overwrite || !File.Exists(EntryFilePath))
                            {
                                Console.WriteLine("{0}", EntryFilePath);
                                try
                                {
                                    var EntryStream = DecompressIfCompressedStream(Entry.CompressedStream);
                                    if (EntryStream.Length > 0)
                                    {
                                        EntryStream.CopyToFile(EntryFilePath);
                                    }
                                }
                                catch (Exception Exception)
                                {
                                    ShowException(Exception);
                                }
                            }
                            if (File.Exists(EntryFilePath))
                            {
                                ListToExpand.Add(EntryFilePath);
                            }
                        }
                    }
                    catch (Exception Exception)
                    {
                        ShowException(Exception);
                    }
                }
                else if (FPS4.IsValid(MagicData))
                {
                    //Console.WriteLine("FPS4");
                    try
                    {
                        var Fps4 = new FPS4(FileStream);
                        foreach (var Entry in Fps4)
                        {
                            var EntryFilePath = FilePath + ".d/" + Entry.Name;
                            if (Overwrite || !File.Exists(EntryFilePath))
                            {
                                Console.WriteLine("{0}", EntryFilePath);
                                try
                                {
                                    var EntryStream = DecompressIfCompressedStream(Entry.Open());
                                    if (EntryStream.Length > 0)
                                    {
                                        EntryStream.CopyToFile(EntryFilePath);
                                    }
                                }
                                catch (Exception Exception)
                                {
                                    ShowException(Exception);
                                }
                            }
                            if (File.Exists(EntryFilePath))
                            {
                                ListToExpand.Add(EntryFilePath);
                            }
                        }
                    }
                    catch (Exception Exception)
                    {
                        ShowException(Exception);
                    }
                }
                else if (TSS.IsValid(MagicData))
                {
                    int RoomId = 0;
                    try { RoomId = int.Parse(Path.GetFileNameWithoutExtension(FilePath)); }
                    catch { }
                    var TxtFile = FilePath + ".txt";

                    Console.WriteLine("{0}", TxtFile);
                    if (Overwrite || !File.Exists(TxtFile))
                    {
                        var Tss = new TSS().Load(FileStream.Slice());

                        using (var TxtStream = File.Open(TxtFile, FileMode.Create, FileAccess.Write))
                            using (var TextWriter = new StreamWriter(TxtStream))
                            {
                                try
                                {
                                    Tss.DumpTexts(TextWriter);
                                }
                                catch (Exception Exception)
                                {
                                    ShowException(Exception);
                                }
                            }
                    }

                    var ScrFile = FilePath + ".scr";
                    Console.WriteLine("{0}", ScrFile);
                    if (Overwrite || !File.Exists(ScrFile))
                    {
                        var Tss = new TSS().Load(FileStream.Slice());

                        using (var TxtStream = File.Open(ScrFile, FileMode.Create, FileAccess.Write))
                            using (var TextWriter = new StreamWriter(TxtStream))
                            {
                                try
                                {
                                    var ErrorString = ConsoleUtils.CaptureError(() => {
                                        Tss.DumpScript(TextWriter);
                                    });
                                }
                                catch (Exception Exception)
                                {
                                    ShowException(Exception);
                                }
                            }
                    }
                }
                else if (TO8CHTX.IsValid(MagicData))
                {
                    var Chtx    = new TO8CHTX(FileStream);
                    var TxtFile = FilePath + ".txt";
                    Console.WriteLine("{0}", TxtFile);
                    if (Overwrite || !File.Exists(TxtFile))
                    {
                        using (var TxtStream = File.Open(TxtFile, FileMode.Create, FileAccess.Write))
                            using (var TextWriter = new StreamWriter(TxtStream))
                            {
                                foreach (var Entry in Chtx.Entries)
                                {
                                    TextWriter.WriteLine("{0}", Entry.Title);
                                    TextWriter.WriteLine("{0}", Entry.TextOriginal);
                                    TextWriter.WriteLine("{0}", Entry.TextTranslated);
                                    TextWriter.WriteLine("");
                                }
                            }
                        //Chtx.Entries[0].Title
                        //Console.WriteLine("CHAT!");
                    }
                }
                else if (SE3.IsValid(MagicData))
                {
                    var Se3 = new SE3().Load(FileStream);
                    foreach (var Entry in Se3.Entries)
                    {
                        var EntryFullNameXma = FilePath + "." + Entry.Name + ".xma";
                        var EntryFullNameWav = FilePath + "." + Entry.Name + ".wav";
                        Console.WriteLine("{0}", EntryFullNameXma);
                        if (Overwrite || !File.Exists(EntryFullNameXma))
                        {
                            Entry.ToXmaWav().CopyToFile(EntryFullNameXma);
                        }
                        if (Overwrite || !File.Exists(EntryFullNameWav))
                        {
                            using (var WavOut = File.Open(EntryFullNameWav, FileMode.Create, FileAccess.Write))
                            {
                                Entry.ToWav(WavOut);
                            }
                        }
                    }
                }
                else if (TXM.IsValid(MagicData))
                {
                    string BasePath;
                    string TxmPath;
                    string TxvPath;

                    if (Path.GetExtension(FilePath).ToLower() == ".txm")
                    {
                        BasePath = Path.GetDirectoryName(FilePath) + "/" + Path.GetFileNameWithoutExtension(FilePath);
                        TxmPath  = BasePath + ".txm";
                        TxvPath  = BasePath + ".txv";
                    }
                    else
                    {
                        var DirectoryPath = Path.GetDirectoryName(FilePath);
                        TxmPath  = DirectoryPath + "/" + Path.GetFileName(FilePath);
                        TxvPath  = DirectoryPath + "/" + (int.Parse(Path.GetFileName(TxmPath)) + 1);
                        BasePath = TxmPath;
                    }

                    var Txm = TXM.FromTxmTxv(File.OpenRead(TxmPath), File.OpenRead(TxvPath));

                    /*
                     * if (Txm.Surface2DEntries.Length > 0 && Txm.Surface3DEntries.Length > 0)
                     * {
                     *      // 3D and 2D surfaces
                     *      //Console.WriteLine("ERROR 3D and 2D SURFACES! (2D: {0}, 3D: {1})", Txm.Surface2DEntries.Length, Txm.Surface3DEntries.Length);
                     * }
                     * else if (Txm.Surface2DEntries.Length > 0)
                     * {
                     *      // 2D Surfaces
                     *      //Console.WriteLine("2D SURFACES! {0}", Txm.Surface2DEntries.Length);
                     * }
                     * else if (Txm.Surface3DEntries.Length > 0)
                     * {
                     *      // 3D Surfaces
                     *      //Console.WriteLine("3D SURFACES! {0}", Txm.Surface3DEntries.Length);
                     * }
                     */

                    foreach (var Entry in Txm.Surface2DEntries)
                    {
                        var ImagePath = BasePath + "." + Entry.Name + ".png";
                        if (Overwrite || !File.Exists(ImagePath))
                        {
                            try
                            {
                                Entry.Bitmap.Save(ImagePath);
                            }
                            catch (Exception Exception)
                            {
                                ShowException(Exception);
                            }
                        }
                    }

                    foreach (var Entry in Txm.Surface3DEntries)
                    {
                        var ImagePath0 = BasePath + "." + Entry.Name + "." + 0 + ".png";
                        if (Overwrite || !File.Exists(ImagePath0))
                        {
                            try
                            {
                                var n = 0;
                                foreach (var Bitmap in Entry.Bitmaps.Bitmaps)
                                {
                                    var ImagePath = BasePath + "." + Entry.Name + "." + n + ".png";
                                    Console.WriteLine("{0}", ImagePath);
                                    if (Overwrite || !File.Exists(ImagePath))
                                    {
                                        Bitmap.Save(ImagePath);
                                    }
                                    n++;
                                }
                            }
                            catch (Exception Exception)
                            {
                                ShowException(Exception);
                            }
                        }
                    }
                }
                else
                {
                }
            }

            // Expand all the queued stuff
            foreach (var Item in ListToExpand)
            {
                try
                {
                    Expand(Item);
                }
                catch (Exception Exception)
                {
                    Console.WriteLine("  ERROR: {0}", Verbose ? Exception.ToString() : Exception.Message.ToString());
                }
            }
        }
Exemplo n.º 25
0
        public void HandleBattlePackDialogs(Stream OldStream, Stream NewStream)
        {
            FPS4 OldFps4;
            FPS4 NewFps4;

            OldFps4 = new FPS4(OldStream.Slice());
            NewFps4 = new FPS4(OldStream.Slice()); // Intended OldStream

            var TranslatedFiles = new ConcurrentDictionary <string, MemoryStream>();

            var Names = new[]
            {
                "BTL_EP_0070_010", "BTL_EP_030_040", "BTL_EP_030_080", "BTL_EP_0950_010",
                "BTL_EP_0960_020", "BTL_EP_1040_020", "BTL_EP_150_170", "BTL_EP_170_050",
                "BTL_EP_210_090", "BTL_EP_270_110", "BTL_EP_270_110_1", "BTL_EP_340_070",
                "BTL_EP_370_050", "BTL_EP_420_080", "BTL_EP_440_040", "BTL_EP_470_030",
                "BTL_EP_490_060_0", "BTL_EP_490_060_1", "BTL_EP_510_050", "BTL_EP_510_080",
                "BTL_EP_640_050", "BTL_EP_650_030", "BTL_EP_650_050", "BTL_LL_MONSTER",
                "MA_VAL_A_05",
            };

            Patcher.Action("Translating Battle Scripts", () =>
            {
                Patcher.ProgressHandler.AddProgressLevel("Traduciendo scripts de batalla...", Names.Length, () =>
                {
                    Patcher.ParallelForeach("Translating", Names, (Name) => Name, (Name) =>
                    {
                        using (var CompressedTssStream = OldFps4[Name].Open())
                        {
                            using (var TssStream = TalesCompression.DecompressStream(CompressedTssStream))
                            {
                                var TssName = Name;
                                var Tss     = new TSS().Load(TssStream);
                                Tss.TranslateTexts((Entry) =>
                                {
                                    //if (Entry == null) return;
                                    var TranslationEntry = Patcher.EntriesByRoom["battle/" + TssName][String.Format("{0:X8}", Entry.Id2)];

                                    int TextCount = Entry.Original.Length;

                                    Entry.TranslateWithTranslationEntry(TranslationEntry);

                                    //Console.WriteLine("{0} : {1}", Entry.Translated[1], TranslationEntry.texts.es[1]);
                                }, (String) =>
                                {
                                    return(null);
                                });

                                var TranslatedCompressedStream = TalesCompression.CreateFromVersion(Patcher.CompressionVersion, Patcher.CompressionFallback).EncodeFile(Tss.Save());

                                TranslatedFiles[Name] = TranslatedCompressedStream;
                            }
                        }
                        Patcher.ProgressHandler.IncrementLevelProgress();
                    });
                });
            });

            Patcher.Action("Reconstructing Battle Scripts Package", () =>
            {
                NewFps4.ClearAllEntries();
                foreach (var Entry in OldFps4.Entries.Values)
                {
                    var EntryName = Entry.Name;
                    if (TranslatedFiles.ContainsKey(EntryName))
                    {
                        NewFps4.CreateEntry(EntryName, TranslatedFiles[EntryName]);
                    }
                    else
                    {
                        NewFps4.CreateEntry(EntryName, Entry.Open());
                    }
                }

                NewFps4.SaveTo(NewStream, DoAlign: false);
            });
        }
Exemplo n.º 26
0
        public static void PatchChat(string chatPath, string patchDir, string outDir, string outMd5 = null, BackgroundWorker worker = null)
        {
            if (!File.Exists(chatPath))
            {
                throw new PatchingException("File not found: " + chatPath);
            }
            if (worker != null)
            {
                worker.ReportProgress(0, "Confirming source file...");
            }
            // if patched file exists and matches, exit early
            string outPath = Path.Combine(outDir, "chat.svo");

            try { CompareMd5Output(outPath, outMd5); return; } catch (PatchingException) { } catch (FileNotFoundException) { }
            CompareMd5(chatPath, "7f0992514818e791ba64a987b6accf88");
            Logger.LogFileData(chatPath, "chat.svo");
            Logger.LogDirData(patchDir, "chat patches");

            if (worker != null)
            {
                worker.ReportProgress(0, "Extracting source file...");
            }
            string extractPath = svoExtractToTempDir(chatPath);
            var    files       = Util.DirectoryGetFilesWorkaround(extractPath);

            int i         = 0;
            int filecount = files.Count(x => Path.GetFileName(x).StartsWith("VC") && Path.GetFileName(x).EndsWith(".DAT"));

            foreach (string file in files)
            {
                string filename = Path.GetFileName(file);
                if (filename.StartsWith("VC") && filename.EndsWith(".DAT"))
                {
                    if (worker != null)
                    {
                        worker.ReportProgress((i / filecount) * 100, "Patching file " + (i + 1) + " of " + filecount + "...");
                    }

                    string decompPath      = tlzcDecompressToTempFile(file);
                    string skitExtractPath = svoExtractToTempDir(decompPath);

                    XdeltaApply(
                        Path.Combine(skitExtractPath, "0003"),
                        Path.Combine(skitExtractPath, "0003.new"),
                        Path.Combine(patchDir, filename + ".xdelta3")
                        );
                    File.Delete(Path.Combine(skitExtractPath, "0003"));
                    File.Move(Path.Combine(skitExtractPath, "0003.new"), Path.Combine(skitExtractPath, "0003"));

                    using (var fps4Skit = new FPS4(decompPath)) {
                        fps4Skit.Alignment = 0x80;
                        fps4Skit.Pack(skitExtractPath, Path.Combine(extractPath, filename + ".new"));
                    }
                    tlzcCompress(Path.Combine(extractPath, filename + ".new"), file);

                    File.Delete(decompPath);
                    File.Delete(Path.Combine(extractPath, filename + ".new"));
                    Util.DeleteDirectoryAggressive(skitExtractPath, true);

                    ++i;
                }
            }

            if (worker != null)
            {
                worker.ReportProgress(100, "Packing modified file...");
            }
            Logger.LogDirData(extractPath, "chat dir patched");
            using (var fps4 = new FPS4(chatPath)) {
                fps4.Alignment = 0x800;
                fps4.Pack(extractPath, outPath);
            }
            Logger.LogFileData(outPath, "chat.svo patched");
            Util.DeleteDirectoryAggressive(extractPath, true);

            if (outMd5 != null)
            {
                CompareMd5Output(outPath, outMd5);
            }
        }
Exemplo n.º 27
0
        public static (DuplicatableStream metrics, DuplicatableStream texture, Dictionary <char, (int w1, int w2)> charToWidthMap) Run(FileFetcher _fc, Config config)
        {
            bool debug         = config.DebugFontOutputPath != null;
            bool adjustMetrics = debug;

            DuplicatableStream metricsWiiStream = _fc.GetFile("rootR.cpk/sys/FontBinary2.bin", Version.W);
            DuplicatableStream textureWiiStream = _fc.GetFile("rootR.cpk/sys/FontTexture2.tex", Version.W);
            DuplicatableStream texturePs3Stream = _fc.GetFile("rootR.cpk/sys/FontTexture2.tex", Version.U);
            FPS4 metricsWiiFps4 = new FPS4(metricsWiiStream);
            DuplicatableStream metricsWiiData = metricsWiiFps4.GetChildByIndex(1).AsFile.DataStream;
            FPS4   textureWiiFps4             = new FPS4(textureWiiStream);
            FPS4   texturePs3Fps4             = new FPS4(texturePs3Stream);
            TXM    textureWiiTxm = new TXM(textureWiiFps4.GetChildByIndex(0).AsFile.DataStream);
            TXV    textureWiiTxv = new TXV(textureWiiTxm, textureWiiFps4.GetChildByIndex(1).AsFile.DataStream, false);
            TXM    texturePs3Txm = new TXM(texturePs3Fps4.GetChildByIndex(0).AsFile.DataStream);
            TXV    texturePs3Txv = new TXV(texturePs3Txm, texturePs3Fps4.GetChildByIndex(1).AsFile.DataStream, false);
            Bitmap bitmapWii     = textureWiiTxv.textures[0].GetBitmaps()[0];
            Bitmap bitmapPs3     = texturePs3Txv.textures[0].GetBitmaps()[0];

            if (debug)
            {
                Directory.CreateDirectory(config.DebugFontOutputPath);
                bitmapWii.Save(Path.Combine(config.DebugFontOutputPath, "wii.png"));
                bitmapPs3.Save(Path.Combine(config.DebugFontOutputPath, "ps3.png"));
            }

            var       img_wii = bitmapWii;
            var       img_ps3 = bitmapPs3;
            const int tile_extent_in_image = 25;
            const int tile_extent_actual   = 24;
            int       tiles_x = (img_wii.Width + 1) / tile_extent_in_image;
            int       tiles_y = (img_wii.Height + 1) / tile_extent_in_image;
            const int ps3_tile_extent_in_image = 37;
            const int ps3_tile_extent_actual   = 36;
            int       ps3_tiles_x = (img_ps3.Width + 1) / ps3_tile_extent_in_image;
            int       ps3_tiles_y = (img_ps3.Height + 1) / ps3_tile_extent_in_image;

            // split into individual tiles and extract source colors
            HashSet <Color> colors    = new HashSet <Color>();
            List <Bitmap>   tiles_wii = new List <Bitmap>();
            List <Bitmap>   tiles_ps3 = new List <Bitmap>();

            for (int ty = 0; ty < tiles_y; ++ty)
            {
                for (int tx = 0; tx < tiles_x; ++tx)
                {
                    var bmp = new Bitmap(tile_extent_actual, tile_extent_actual);
                    for (int y = 0; y < tile_extent_actual; ++y)
                    {
                        for (int x = 0; x < tile_extent_actual; ++x)
                        {
                            var px = img_wii.GetPixel(tx * tile_extent_in_image + x, ty * tile_extent_in_image + y);
                            colors.Add(px);
                            bmp.SetPixel(x, y, px);
                        }
                    }
                    tiles_wii.Add(bmp);
                }
            }
            for (int ty = 0; ty < ps3_tiles_y; ++ty)
            {
                for (int tx = 0; tx < ps3_tiles_x; ++tx)
                {
                    var bmp = new Bitmap(ps3_tile_extent_actual, ps3_tile_extent_actual);
                    for (int y = 0; y < ps3_tile_extent_actual; ++y)
                    {
                        for (int x = 0; x < ps3_tile_extent_actual; ++x)
                        {
                            var px = img_ps3.GetPixel(tx * ps3_tile_extent_in_image + x, ty * ps3_tile_extent_in_image + y);
                            bmp.SetPixel(x, y, px);
                        }
                    }
                    tiles_ps3.Add(bmp);
                }
            }

            // inject ps3 tiles over wii tiles
            List <(int where, int ps3where, string chars)> charsets = new List <(int where, int ps3where, string chars)>();

            charsets.Add((0, 0, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
            charsets.Add((243, 74, ",."));
            charsets.Add((246, 77, ":;?!_"));
            charsets.Add((254, 83, "/\\~|…"));
            charsets.Add((260, 118, "‘"));
            charsets.Add((261, 118, "’"));
            charsets.Add((262, 119, "“"));
            charsets.Add((263, 119, "”"));
            charsets.Add((264, 93, "()[]{}"));
            charsets.Add((276, 105, "+"));
            charsets.Add((277, 82, "-"));             // copy the dash minus instead of the math minus, looks better in text flow
            charsets.Add((278, 107, "±×÷=≠<>≤≥"));
            charsets.Add((289, 118, "'\""));
            charsets.Add((293, 122, "$%#&*@"));

            Dictionary <char, (int w1, int w2)> charToWidthMap = new Dictionary <char, (int w1, int w2)>();

            byte[] metrics = new byte[metricsWiiData.Length];
            metricsWiiData.Read(metrics, 0, metrics.Length);

            foreach (var charset in charsets)
            {
                int where = charset.where;
                int ps3where = charset.ps3where;
                foreach (char ch in charset.chars)
                {
                    var wiitile       = tiles_wii[where];
                    var averagescaled = DownscaleTileFromPs3ToWiiWithUnweightedAverageScaling(tiles_ps3[ps3where]);
                    //var downscaled = DownscaleTileFromPs3ToWiiWithWeightedScaling(tiles_ps3[ps3where]);
                    var downscaled = averagescaled;
                    PosterizeImage(wiitile, downscaled, colors, tile_extent_actual);
                    PosterizeImage(averagescaled, averagescaled, colors, tile_extent_actual);
                    if (debug)
                    {
                        wiitile.Save(Path.Combine(config.DebugFontOutputPath, string.Format("wii_new_{0:D4}.png", where)));
                    }

                    int cutoff_1    = 180;
                    int cutoff_2    = 220;
                    int leftwhere   = where * 8 + 0;
                    int rightwhere  = where * 8 + 1;
                    int leftwhere2  = where * 8 + 4;
                    int rightwhere2 = where * 8 + 5;

                    // forcing vertical extents to be the same for all, because text looks *really weird* in english if lines have different heights
                    // for digits, forcing horizontal extents to be the same as well so they look nice in vertical lists
                    bool isDigit = ch == '0' || ch == '1' || ch == '2' || ch == '3' || ch == '4' || ch == '5' || ch == '6' || ch == '7' || ch == '8' || ch == '9';
                    if (isDigit)
                    {
                        metrics[leftwhere]  = ch == '1' ? (byte)(6) : ch == '2' ? (byte)(6) : (byte)(7);
                        metrics[rightwhere] = ch == '1' ? (byte)(8) : ch == '2' ? (byte)(8) : (byte)(7);
                        //metrics[leftwhere2] = ch == '1' ? (byte)(7) : ch == '2' ? (byte)(7) : (byte)(8);
                        //metrics[rightwhere2] = ch == '1' ? (byte)(9) : ch == '2' ? (byte)(9) : (byte)(8);
                    }
                    else
                    {
                        metrics[leftwhere]  = (byte)MeasureAlphaFromLeft(averagescaled, cutoff_1);
                        metrics[rightwhere] = (byte)MeasureAlphaFromRight(averagescaled, cutoff_1);
                        //metrics[leftwhere2] = (byte)MeasureAlphaFromLeft(averagescaled, cutoff_2);
                        //metrics[rightwhere2] = (byte)MeasureAlphaFromRight(averagescaled, cutoff_2);
                    }

                    switch (ch)
                    {
                    case 'j':
                    case ';':
                        metrics[leftwhere] += 1;
                        break;

                    case 'A':
                    case 'P':
                    case 'Q':
                    case 'T':
                    case 'Y':
                    case 'W':
                    case 'f':
                    case 's':
                    case 'w':
                    case 'y':
                    case '[':
                        metrics[rightwhere] += 1;
                        break;

                    case 't':
                        metrics[leftwhere]  += 1;
                        metrics[rightwhere] += 1;
                        break;

                    default:
                        break;
                    }

                    metrics[leftwhere2]  = metrics[leftwhere];
                    metrics[rightwhere2] = metrics[rightwhere];

                    switch (ch)
                    {
                    case '.':
                    case ',':
                        metrics[leftwhere2] += 1;
                        metrics[rightwhere] += 1;
                        break;

                    default:
                        break;
                    }

                    metrics[where * 8 + 2] = 0;                     //(byte)MeasureAlphaFromTop(test, cutoff_1);
                    metrics[where * 8 + 3] = 4;                     //(byte)MeasureAlphaFromBottom(test, cutoff_1);
                    metrics[where * 8 + 6] = 0;                     //(byte)MeasureAlphaFromTop(test, cutoff_2);
                    metrics[where * 8 + 7] = 4;                     //(byte)MeasureAlphaFromBottom(test, cutoff_2);

                    int width1 = tile_extent_actual - (metrics[leftwhere] + metrics[rightwhere]);
                    int width2 = tile_extent_actual - (metrics[leftwhere2] + metrics[rightwhere2]);
                    charToWidthMap.Add(ch, (width1, width2));

                    ++where;
                    ++ps3where;
                }
            }

            // manually generate good metrics for space; see also code patches in main.dol
            metrics[0x6F70] = 10;
            metrics[0x6F71] = 10;
            metrics[0x6F72] = 0;
            metrics[0x6F73] = 4;
            metrics[0x6F74] = 10;
            metrics[0x6F75] = 10;
            metrics[0x6F76] = 0;
            metrics[0x6F77] = 4;
            charToWidthMap.Add(' ', (tile_extent_actual - 20, tile_extent_actual - 20));

            // write out visual representation of font metrics for adjustments
            if (adjustMetrics)
            {
                foreach (var charset in charsets)
                {
                    int where = charset.where;
                    foreach (char ch in charset.chars)
                    {
                        int factor = 10;
                        var test   = PointScale(tiles_wii[where], factor);

                        for (int metricsset = 0; metricsset < 2; ++metricsset)
                        {
                            Color col = metricsset == 0 ? Color.Red : Color.Yellow;
                            int   xl  = (metrics[where * 8 + metricsset * 4] - 1) * factor + factor - 1;
                            int   xr  = (tiles_wii[where].Width - metrics[where * 8 + metricsset * 4 + 1]) * factor;
                            int   yt  = (metrics[where * 8 + metricsset * 4 + 2] - 1) * factor + factor - 1;
                            int   yb  = (tiles_wii[where].Width - metrics[where * 8 + metricsset * 4 + 3]) * factor;
                            for (int y = 0; y < test.Height; ++y)
                            {
                                if (xl >= 0 && xl < test.Width)
                                {
                                    test.SetPixel(xl, y, col);
                                }
                                if (xr >= 0 && xr < test.Width)
                                {
                                    test.SetPixel(xr, y, col);
                                }
                            }
                            for (int x = 0; x < test.Width; ++x)
                            {
                                if (yt >= 0 && yt < test.Height)
                                {
                                    test.SetPixel(x, yt, col);
                                }
                                if (yb >= 0 && yb < test.Height)
                                {
                                    test.SetPixel(x, yb, col);
                                }
                            }
                        }

                        PointScale(test, 3).Save(Path.Combine(config.DebugFontOutputPath, string.Format("metrics_view_{0:D4}.png", where)));

                        ++where;
                    }
                }
            }

            // join indvidiual tiles back into full texture
            int idx = 0;

            for (int ty = 0; ty < tiles_y; ++ty)
            {
                for (int tx = 0; tx < tiles_x; ++tx)
                {
                    var bmp = tiles_wii[idx];
                    for (int y = 0; y < tile_extent_actual; ++y)
                    {
                        for (int x = 0; x < tile_extent_actual; ++x)
                        {
                            var px = bmp.GetPixel(x, y);
                            img_wii.SetPixel(tx * tile_extent_in_image + x, ty * tile_extent_in_image + y, px);
                        }
                    }
                    ++idx;
                }
            }

            if (debug)
            {
                img_wii.Save(Path.Combine(config.DebugFontOutputPath, "wii_new.png"));
            }

            // inject metrics
            DuplicatableStream outputMetricsStream;
            {
                Stream stream = metricsWiiStream.Duplicate().CopyToMemory();
                stream.Position = 0x43E0;
                stream.Write(metrics);

                stream.Position = 0;
                byte[] data = new byte[stream.Length];
                stream.Read(data, 0, data.Length);
                outputMetricsStream = new HyoutaUtils.Streams.DuplicatableByteArrayStream(data);
            }

            // encode texture
            DuplicatableStream outputTextureStream;

            {
                Stream stream = textureWiiStream.Duplicate().CopyToMemory();
                stream.Position = 0x80100;
                List <(int idx, ushort v)> stuff = new List <(int idx, ushort v)>();
                for (int i = 0; i < 16; ++i)
                {
                    stuff.Add((i, stream.ReadUInt16().FromEndian(EndianUtils.Endianness.BigEndian)));
                }

                stream.Position = 0x100;
                var  pxit    = new HyoutaTools.Textures.PixelOrderIterators.TiledPixelOrderIterator(img_wii.Width, img_wii.Height, 8, 8);
                byte storage = 0;
                bool even    = false;
                foreach (var px in pxit)
                {
                    if (px.X < img_wii.Width && px.Y < img_wii.Height)
                    {
                        Color  col    = img_wii.GetPixel(px.X, px.Y);
                        ushort value  = HyoutaTools.Textures.ColorFetchingIterators.ColorFetcherGrey8Alpha8.ColorToGrey8Alpha8(col);
                        var    colidx = stuff.First(x => x.v == value).idx;
                        if (!even)
                        {
                            storage = (byte)colidx;
                        }
                        else
                        {
                            storage = (byte)(storage << 4 | (byte)colidx);
                            stream.WriteByte(storage);
                        }
                        even = !even;
                    }
                }

                stream.Position = 0;
                byte[] data = new byte[stream.Length];
                stream.Read(data, 0, data.Length);
                outputTextureStream = new HyoutaUtils.Streams.DuplicatableByteArrayStream(data);
            }

            return(outputMetricsStream, outputTextureStream, charToWidthMap);
        }
Exemplo n.º 28
0
        public static void PatchUI(string uiPath, string patchDir, string outDir, string outMd5 = null, BackgroundWorker worker = null)
        {
            if (!File.Exists(uiPath))
            {
                throw new PatchingException("File not found: " + uiPath);
            }
            if (worker != null)
            {
                worker.ReportProgress(0, "Confirming source file...");
            }
            // if patched file exists and matches, exit early
            string outPath = Path.Combine(outDir, "UI.svo");

            try { CompareMd5Output(outPath, outMd5); return; } catch (PatchingException) { } catch (FileNotFoundException) { }
            CompareMd5(uiPath, "9d0a479c838c4811e5df5f6a6815071d");
            Logger.LogFileData(uiPath, "UI.svo");
            Logger.LogDirData(patchDir, "UI patches");

            // extract
            if (worker != null)
            {
                worker.ReportProgress(0, "Extracting source file...");
            }
            string extractPath = svoExtractToTempDir(uiPath);

            // patch
            int i     = 0;
            var files = Util.DirectoryGetFilesWorkaround(patchDir);

            foreach (string patch in files)
            {
                if (worker != null)
                {
                    worker.ReportProgress((i / files.Length) * 100, "Patching file " + (i + 1) + " of " + files.Length + "...");
                }
                string fileName = Path.GetFileNameWithoutExtension(patch);

                string sourcePath  = Path.Combine(extractPath, fileName);
                string patchedPath = TempUtil.GetTempFileName();
                XdeltaApply(sourcePath, patchedPath, patch);
                File.Delete(sourcePath);
                File.Move(patchedPath, sourcePath);

                ++i;
            }

            // copy unchanged 360 english files over japanese ones
            File.Copy(Path.Combine(extractPath, "MINIGAMEISHI_E.TXV"), Path.Combine(extractPath, "MINIGAMEISHI.TXV"), true);
            File.Copy(Path.Combine(extractPath, "EVENTMAP_E.TXV"), Path.Combine(extractPath, "EVENTMAP.TXV"), true);

            // copy english poker text textures to new PS3 poker deck
            BlockCopy(Path.Combine(extractPath, "MINIGAMEPOKER_E.TXV"), 0x0, Path.Combine(extractPath, "MINIGAMEPOKER.TXV"), 0x0, 0x6AB900);
            BlockCopy(Path.Combine(extractPath, "MINIGAMEPOKER_E.TXV"), 0x14519E0, Path.Combine(extractPath, "MINIGAMEPOKER.TXV"), 0x14519E0, 0x5E620);

            // pack
            if (worker != null)
            {
                worker.ReportProgress(100, "Packing modified file...");
            }
            Logger.LogDirData(extractPath, "UI dir patched");
            using (var fps4btl = new FPS4(uiPath)) {
                fps4btl.Alignment = 0x800;
                fps4btl.Pack(extractPath, outPath);
            }
            Logger.LogFileData(outPath, "UI.svo patched");
            Util.DeleteDirectoryAggressive(extractPath, true);

            if (outMd5 != null)
            {
                CompareMd5Output(outPath, outMd5);
            }
        }
Exemplo n.º 29
0
        public static void PatchEffect(string effectPath, string patchDir, string outDir, string outMd5 = null, BackgroundWorker worker = null)
        {
            if (!File.Exists(effectPath))
            {
                throw new PatchingException("File not found: " + effectPath);
            }
            if (worker != null)
            {
                worker.ReportProgress(0, "Confirming source file...");
            }
            // if patched file exists and matches, exit early
            string outPath = Path.Combine(outDir, "effect.svo");

            try { CompareMd5Output(outPath, outMd5); return; } catch (PatchingException) { } catch (FileNotFoundException) { }
            CompareMd5(effectPath, "ada3bdb2e2ca481b44bc9e209b019dc8");
            Logger.LogFileData(effectPath, "effect.svo");
            Logger.LogDirData(patchDir, "effect patches");

            // extract effect.svo
            if (worker != null)
            {
                worker.ReportProgress(0, "Extracting source file...");
            }
            string extractPath = svoExtractToTempDir(effectPath);

            if (worker != null)
            {
                worker.ReportProgress(0, "Patching files...");
            }

            // image assets for SURPRISE ENCOUNTER! and so on
            string surpriseJpn = tlzcDecompressToTempFile(Path.Combine(extractPath, "E_A023.DAT"));
            string surpriseEng = tlzcDecompressToTempFile(Path.Combine(extractPath, "E_A034.DAT"));

            BlockCopy(surpriseEng, 0x100, surpriseJpn, 0x100, 0x80000);
            tlzcCompress(surpriseJpn, Path.Combine(extractPath, "E_A023.DAT"));
            System.IO.File.Delete(surpriseJpn);
            System.IO.File.Delete(surpriseEng);

            // image assets for game over screen
            string gameover = tlzcDecompressToTempFile(Path.Combine(extractPath, "E_A104_GAMEOVER.DAT"));

            BlockCopy(gameover, 0x55D80, gameover, 0xD80, 0x55000);
            BlockCopy(gameover, 0x55D80, gameover, 0xAAD80, 0x55000);
            tlzcCompress(gameover, Path.Combine(extractPath, "E_A104_GAMEOVER.DAT"));
            System.IO.File.Delete(gameover);

            // image assets for dice minigame
            string dice1 = tlzcDecompressToTempFile(Path.Combine(extractPath, "E_MG_STONERESULT01.DAT"));

            BlockCopy(dice1, 0x100, dice1, 0x100100, 0x100000);
            tlzcCompress(dice1, Path.Combine(extractPath, "E_MG_STONERESULT01.DAT"));
            System.IO.File.Delete(dice1);

            string dice2 = tlzcDecompressToTempFile(Path.Combine(extractPath, "E_MG_STONERESULT02.DAT"));

            BlockCopy(dice2, 0x100, dice2, 0x100100, 0x100000);
            tlzcCompress(dice2, Path.Combine(extractPath, "E_MG_STONERESULT02.DAT"));
            System.IO.File.Delete(dice2);

            // remaining assets with xdelta patches
            foreach (string patch in Util.DirectoryGetFilesWorkaround(patchDir))
            {
                string fileName = Path.GetFileNameWithoutExtension(patch);

                string sourcePath       = Path.Combine(extractPath, fileName + ".DAT");
                string decompressedPath = tlzcDecompressToTempFile(sourcePath);
                string patchedPath      = TempUtil.GetTempFileName();
                XdeltaApply(decompressedPath, patchedPath, patch);
                tlzcCompress(patchedPath, sourcePath);

                System.IO.File.Delete(decompressedPath);
                System.IO.File.Delete(patchedPath);
            }

            // pack up modified effect.svo
            if (worker != null)
            {
                worker.ReportProgress(100, "Packing modified file...");
            }
            Logger.LogDirData(extractPath, "effect dir patched");
            using (var fps4 = new FPS4(effectPath)) {
                fps4.Alignment = 0x800;
                fps4.Pack(extractPath, outPath);
            }
            Logger.LogFileData(outPath, "effect.svo patched");

            // clean up
            Util.DeleteDirectoryAggressive(extractPath, true);

            if (outMd5 != null)
            {
                CompareMd5Output(outPath, outMd5);
            }
        }
Exemplo n.º 30
0
 public FPS4FileSystem(FPS4 FPS4)
 {
     this.FPS4 = FPS4;
 }