Exemple #1
0
        internal static Stream InjectEnglishContainedVoice(Config config, FileFetcher _fc, string name, DuplicatableStream wstream, DuplicatableStream jstream, DuplicatableStream ustream, ContainedVoiceInfo cvi, SkitTexCache skitTexCache)
        {
            var fps4         = new HyoutaTools.Tales.Vesperia.FPS4.FPS4(wstream.Duplicate());
            var se3stream    = fps4.GetChildByIndex(cvi.SE3Index).AsFile.DataStream;
            var se3          = new HyoutaTools.Tales.Vesperia.SE3.SE3(se3stream.Duplicate(), EndianUtils.Endianness.BigEndian, TextUtils.GameTextEncoding.ASCII);
            var se3ms        = se3.ExtractSe3HeaderStream();
            var nubms        = se3.ExtractNubStream();
            var nubstream    = new DuplicatableByteArrayStream(nubms.CopyToByteArrayAndDispose());
            var newnubstream = RebuildNubStream(nubstream, Path.Combine(config.EnglishVoiceProcessingDir, "other"), cvi.WiiType, x => Path.GetFileNameWithoutExtension(name));
            var newse3stream = new MemoryStream();

            se3ms.Position        = 0;
            newnubstream.Position = 0;
            StreamUtils.CopyStream(se3ms, newse3stream);
            StreamUtils.CopyStream(newnubstream, newse3stream);

            if (cvi.IsSkit)
            {
                using (var texIdStream = fps4.GetChildByIndex(3).AsFile.DataStream.Duplicate().CopyToByteArrayStreamAndDispose()) {
                    int    idx    = 4;
                    uint[] texIds = texIdStream.ReadUInt32Array(texIdStream.Length / 4, EndianUtils.Endianness.BigEndian);
                    foreach (uint texId in texIds)
                    {
                        skitTexCache.AddTextureIfNotExists(texId, fps4.GetChildByIndex(idx).AsFile.DataStream.Duplicate().CopyToByteArrayStreamAndDispose());
                        ++idx;
                    }
                }
            }

            newse3stream.Position = 0;
            MemoryStream newfps4stream = new MemoryStream();

            using (var ufps4 = new HyoutaTools.Tales.Vesperia.FPS4.FPS4(ustream.Duplicate())) {
                uint[] utexIds = null;
                if (cvi.IsSkit)
                {
                    using (var texIdStream = ufps4.GetChildByIndex(3).AsFile.DataStream.Duplicate().CopyToByteArrayStreamAndDispose()) {
                        utexIds = texIdStream.ReadUInt32Array(texIdStream.Length / 4, EndianUtils.Endianness.BigEndian);
                    }
                }

                List <HyoutaTools.Tales.Vesperia.FPS4.PackFileInfo> packFileInfos = new List <HyoutaTools.Tales.Vesperia.FPS4.PackFileInfo>(fps4.Files.Count);
                for (int i = 0; i < (cvi.IsSkit ? ufps4 : fps4).Files.Count - 1; ++i)
                {
                    var pf = new HyoutaTools.Tales.Vesperia.FPS4.PackFileInfo();
                    pf.Name = (cvi.IsSkit ? ufps4 : fps4).Files[i].FileName;
                    if (i == cvi.SE3Index)
                    {
                        pf.DataStream = new DuplicatableByteArrayStream(newse3stream.CopyToByteArrayAndDispose());
                    }
                    else if (cvi.IsSkit && (i == 0 || i == 2 || i == 3))
                    {
                        // copy over the actual skit script/timing from the EN version so the voice timing and lipsync matches with the skit
                        pf.DataStream = ufps4.GetChildByIndex(i).AsFile.DataStream.Duplicate();
                    }
                    else if (cvi.IsSkit && i >= 4)
                    {
                        uint texId = NormalizePs3SkitTextureIdForWii(utexIds[i - 4]);
                        try {
                            pf.DataStream = skitTexCache.GetTextureStream(texId);
                        } catch (Exception ex) {
                            Console.WriteLine("ERROR: Failed to get skit texture with ID 0x" + texId.ToString("x4"));
                            Console.WriteLine("       tex name: " + new SkitTexCache.SkitTex()
                            {
                                Stream = ufps4.GetChildByIndex(i).AsFile.DataStream.Duplicate()
                            }.ToString());
                            throw ex;
                        }
                    }
                    else
                    {
                        pf.DataStream = fps4.GetChildByIndex(i).AsFile.DataStream.Duplicate();
                    }
                    pf.Length = pf.DataStream.Length;
                    packFileInfos.Add(pf);
                }
                packFileInfos = HyoutaTools.Tales.Vesperia.FPS4.FPS4.DetectDuplicates(packFileInfos);
                HyoutaTools.Tales.Vesperia.FPS4.FPS4.Pack(packFileInfos, newfps4stream, fps4.ContentBitmask, EndianUtils.Endianness.BigEndian, fps4.Unknown2, cvi.IsSkit ? null : wstream.Duplicate(), fps4.ArchiveName, fps4.FirstFileStart, 0x20);
            }

            //using (var fs = new FileStream(Path.Combine(@"c:\__graces\______fps4repacktest\", name.Replace("/", "_") + "_old.fps4"), FileMode.Create)) {
            //	using (var wcpy = wstream.Duplicate()) {
            //		wcpy.Position = 0;
            //		StreamUtils.CopyStream(wcpy, fs);
            //	}
            //}
            //using (var fs = new FileStream(Path.Combine(@"c:\__graces\______fps4repacktest\", name.Replace("/", "_") + "_new.fps4"), FileMode.Create)) {
            //	newfps4stream.Position = 0;
            //	StreamUtils.CopyStream(newfps4stream, fs);
            //}

            newfps4stream.Position = 0;
            return(newfps4stream);
        }
Exemple #2
0
        public static List <MemChunk> FindFreeMemoryInFontTexture(MemoryStream fontStream)
        {
            DuplicatableStream textureWiiStream = new DuplicatableByteArrayStream(fontStream.CopyToByteArray());

            HyoutaTools.Tales.Vesperia.FPS4.FPS4   textureWiiFps4 = new HyoutaTools.Tales.Vesperia.FPS4.FPS4(textureWiiStream);
            HyoutaTools.Tales.Vesperia.Texture.TXM textureWiiTxm  = new HyoutaTools.Tales.Vesperia.Texture.TXM(textureWiiFps4.GetChildByIndex(0).AsFile.DataStream);
            HyoutaTools.Tales.Vesperia.Texture.TXV textureWiiTxv  = new HyoutaTools.Tales.Vesperia.Texture.TXV(textureWiiTxm, textureWiiFps4.GetChildByIndex(1).AsFile.DataStream, false);
            Bitmap bitmapWii = textureWiiTxv.textures[2].GetBitmaps()[0];
            {
                for (int y = 0; y < bitmapWii.Height; ++y)
                {
                    for (int x = 0; x < bitmapWii.Width; ++x)
                    {
                        Color color;
                        switch (IdentifyPixel(x, y))
                        {
                        case TileIdentification.UsedTile:
                            color = Color.FromArgb(0, 255, 0);
                            break;

                        case TileIdentification.UnusedTile:
                            color = Color.FromArgb(0, 0, 255);
                            break;

                        default:
                            throw new Exception("???");
                        }
                        bitmapWii.SetPixel(x, y, color);
                    }
                }
            }

            var          pxit    = new HyoutaTools.Textures.PixelOrderIterators.TiledPixelOrderIterator(bitmapWii.Width, bitmapWii.Height, 8, 8);
            MemoryStream stream  = new MemoryStream();
            byte         storage = 0;
            bool         even    = false;

            foreach (var px in pxit)
            {
                if (px.X < bitmapWii.Width && px.Y < bitmapWii.Height)
                {
                    Color col         = bitmapWii.GetPixel(px.X, px.Y);
                    bool  pixelUnused = col.B > 0;
                    var   colidx      = pixelUnused ? 0xF : 0x0;
                    if (!even)
                    {
                        storage = (byte)colidx;
                    }
                    else
                    {
                        storage = (byte)(storage << 4 | (byte)colidx);
                        stream.WriteByte(storage == 0xFF ? (byte)1 : (byte)0);
                    }
                    even = !even;
                }
            }

            List <MemChunk> chunks = new List <MemChunk>();
            uint            offset = textureWiiFps4.Files[1].Location.Value + textureWiiTxv.textures[2].TXM.TxvLocation;
            long            len    = stream.Length;
            long            startOfLastSafeBlock = -1;
            var             fontMapper           = new FontMapper(0xE0000000 - textureWiiFps4.Files[1].Location.Value);

            stream.Position = 0;
            for (long i = 0; i <= len; ++i)
            {
                bool safeToWriteTo = i == len ? false : stream.ReadUInt8() == 1;
                if (safeToWriteTo && startOfLastSafeBlock == -1)
                {
                    // start of block
                    startOfLastSafeBlock = i;
                }
                else if (!safeToWriteTo && startOfLastSafeBlock != -1)
                {
                    // end of block
                    long     start  = startOfLastSafeBlock;
                    long     length = i - startOfLastSafeBlock;
                    MemChunk mc     = new MemChunk();
                    mc.Address    = (uint)(start + offset);
                    mc.FreeBytes  = (uint)length;
                    mc.File       = fontStream;
                    mc.Mapper     = fontMapper;
                    mc.IsInternal = false;
                    chunks.Add(mc);
                    startOfLastSafeBlock = -1;
                }
            }

            return(chunks);
        }
Exemple #3
0
        public static void Setup(Config config, string targetpath)
        {
            Directory.CreateDirectory(targetpath);
            var _fc   = new FileFetcher(config);
            var rootW = _fc.TryGetContainer("rootR.cpk", Version.W);
            var rootU = _fc.TryGetContainer("rootR.cpk", Version.U);

            StringBuilder sb = new StringBuilder();

            var defstreamW = rootW.GetChildByName("snd/init/StrConfig.stp").AsFile.DataStream;
            var defstreamU = rootU.GetChildByName("snd/init/StrConfig.stp").AsFile.DataStream;
            var defW       = new SPKD(defstreamW);
            var defU       = new SPKD(defstreamU);
            List <SPKD.SpkdPackFileData> defWPack = defW.GetPackData();

            SHBP hashVobtletcU = null;
            iPck lipVobtletcU  = null;
            NUB  nubVobtletcU  = null;

            foreach (NubInfo nubInfo in Nubs)
            {
                var hashStreamW = defW.GetChildByName(nubInfo.Name + ".1")?.AsFile.DataStream;
                var hashStreamU = defU.GetChildByName(nubInfo.Name + ".1")?.AsFile.DataStream;
                var lipStreamU  = defU.GetChildByName(nubInfo.Name + ".2")?.AsFile.DataStream;
                DuplicatableStream lipStreamUDec = null;
                if (lipStreamU != null)
                {
                    MemoryStream ms = new MemoryStream();
                    compto.complib.DecodeStream(lipStreamU, ms, 0, 0, true);
                    lipStreamUDec          = ms.CopyToByteArrayStreamAndDispose();
                    lipStreamUDec.Position = 0;
                }
                var nubStreamU = rootU.GetChildByName("snd/strpck/" + nubInfo.Name + ".nub").AsFile.DataStream;

                var hashW = hashStreamW != null ? new SHBP(hashStreamW) : null;
                var hashU = hashStreamU != null ? new SHBP(hashStreamU) : null;
                var lipU  = lipStreamUDec != null ? new iPck(lipStreamUDec) : null;
                var nubU  = new NUB(nubStreamU, EndianUtils.Endianness.BigEndian);

                if (nubInfo.Name == "VOBTLETC")
                {
                    // the Wii VOBTL was split into two files VOBTL and VOBTLETC in PS3, so we need to do some stuff to put them back together
                    hashVobtletcU = hashU;
                    lipVobtletcU  = lipU;
                    nubVobtletcU  = nubU;
                    continue;
                }

                Console.WriteLine("Extracting files for " + nubInfo.Name + "...");

                List <NubFileRef> filesToExtract = new List <NubFileRef>();
                if (hashW != null && hashU != null)
                {
                    Dictionary <uint, NubFileRef> hashToNubfileMap = new Dictionary <uint, NubFileRef>();
                    for (int i = 0; i < hashU.Hashes.Count; ++i)
                    {
                        uint       hash = hashU.Hashes[i];
                        NubFileRef nfr  = new NubFileRef()
                        {
                            Nub = nubU, Index = i, Lipsync = lipU.Data[i]
                        };
                        if (hashToNubfileMap.ContainsKey(hash))
                        {
                            throw new Exception("duplicate hash key");
                        }
                        hashToNubfileMap.Add(hash, nfr);
                    }

                    if (nubInfo.Name == "VOBTL")
                    {
                        for (int i = 0; i < hashVobtletcU.Hashes.Count; ++i)
                        {
                            uint       hash = hashVobtletcU.Hashes[i];
                            NubFileRef nfr  = new NubFileRef()
                            {
                                Nub = nubVobtletcU, Index = i, Lipsync = lipVobtletcU.Data[i]
                            };
                            if (hashToNubfileMap.ContainsKey(hash))
                            {
                                throw new Exception("duplicate hash key");
                            }
                            hashToNubfileMap.Add(hash, nfr);
                        }
                    }

                    for (int i = 0; i < hashW.Hashes.Count; ++i)
                    {
                        uint hash = hashW.Hashes[i];
                        filesToExtract.Add(hashToNubfileMap[hash]);
                    }
                }
                else
                {
                    for (int i = 0; i < nubU.EntryCount; ++i)
                    {
                        filesToExtract.Add(new NubFileRef()
                        {
                            Nub = nubU, Index = i
                        });
                    }
                }

                List <byte[]> lipData = lipU != null ? new List <byte[]>() : null;

                string dir = Path.Combine(targetpath, nubInfo.Name);
                Directory.CreateDirectory(dir);
                for (int i = 0; i < filesToExtract.Count; ++i)
                {
                    var nfr = filesToExtract[i];

                    if (lipData != null)
                    {
                        lipData.Add(nfr.Lipsync);
                    }

                    using (var audiofilestream = nfr.Nub.GetChildByIndex(nfr.Index).AsFile.DataStream.Duplicate()) {
                        string path = Path.Combine(dir, string.Format("{0:D8}.{1}", i, nubInfo.EngType));
                        using (var fs = new FileStream(path, FileMode.Create)) {
                            audiofilestream.Position = 0;
                            StreamUtils.CopyStream(audiofilestream, fs);
                        }
                    }
                    GenerateConversion(sb, nubInfo.Name, i.ToString("D8"), nubInfo.EngType, nubInfo.WiiType, nubInfo.WiiSampleRate);
                }

                if (lipData != null)
                {
                    using (var newlipstream = new iPck(lipData).WriteToStream(EndianUtils.Endianness.BigEndian)) {
                        newlipstream.Position = 0;
                        using (MemoryStream ms = new MemoryStream()) {
                            compto.complib.EncodeStream(newlipstream, ms, 0, 1, true);
                            defWPack.First(x => x.Name == nubInfo.Name).File2 = ms.CopyToByteArrayStreamAndDispose();
                        }
                    }
                }
            }

            using (var newspkd = SPKD.Pack(defWPack))
                using (var fs = new FileStream(Path.Combine(targetpath, "StrConfig.stp"), FileMode.Create)) {
                    newspkd.Position = 0;
                    StreamUtils.CopyStream(newspkd, fs);
                }

            string otherdir = Path.Combine(targetpath, "other");

            Directory.CreateDirectory(otherdir);
            foreach (var cvi in ContainedVoices)
            {
                for (int i = cvi.StartNumber; i <= cvi.EndNumber; ++i)
                {
                    string path = string.Format(cvi.BaseName, i);
                    Console.WriteLine("Extracting " + path + "...");
                    string fname      = Path.GetFileNameWithoutExtension(path);
                    var    fps4stream = rootU.GetChildByName(path).AsFile.DataStream;
                    var    fps4       = new HyoutaTools.Tales.Vesperia.FPS4.FPS4(fps4stream);
                    var    se3stream  = fps4.GetChildByIndex(cvi.SE3Index).AsFile.DataStream;
                    var    ms         = new HyoutaTools.Tales.Vesperia.SE3.SE3(se3stream.Duplicate(), EndianUtils.Endianness.BigEndian, TextUtils.GameTextEncoding.ASCII).ExtractNubStream();
                    var    nub        = new NUB(ms.CopyToByteArrayStreamAndDispose(), EndianUtils.Endianness.BigEndian);
                    using (var audiofilestream = nub.GetChildByIndex(0).AsFile.DataStream.Duplicate()) {
                        string otherpath = Path.Combine(otherdir, string.Format("{0}.{1}", fname, cvi.EngType));
                        using (var fs = new FileStream(otherpath, FileMode.Create)) {
                            audiofilestream.Position = 0;
                            StreamUtils.CopyStream(audiofilestream, fs);
                        }
                    }
                    GenerateConversion(sb, "other", fname, cvi.EngType, cvi.WiiType, cvi.WiiSampleRate);
                }
            }

            File.WriteAllText(Path.Combine(targetpath, "convert_voices.bat"), sb.ToString());

            return;
        }