public override void Read(Stream s)
        {
            _dataList = new List <TFString>();

            s.Seek(0x24, SeekOrigin.Begin);

            var pointer1 = s.ReadValueS32(Endianness);

            if (pointer1 != -1)
            {
                s.Seek(pointer1, SeekOrigin.Begin);

                var pointer2 = s.ReadValueS32(Endianness);

                s.Seek(pointer2, SeekOrigin.Begin);

                var str = s.ReadStringZ(Encoding);
                if (!string.IsNullOrEmpty(str.TrimEnd('\0')))
                {
                    str = Yakuza0Project.ReadingReplacements(str);
                }

                var item = new TFString
                {
                    FileId      = Id,
                    Offset      = pointer2,
                    Section     = pointer1.ToString("X8"),
                    Original    = str,
                    Translation = str,
                    Visible     = !string.IsNullOrEmpty(str.TrimEnd('\0'))
                };

                _dataList.Add(item);
            }
        }
Beispiel #2
0
        private TFString ReadString(Stream s)
        {
            var stringOffset = s.ReadValueS32(Endianness);
            var pos          = s.Position;

            var value = new TFString {
                FileId = Id, Offset = stringOffset, Visible = false
            };

            if (stringOffset != 0)
            {
                s.Seek(stringOffset, SeekOrigin.Begin);

                var str = s.ReadStringZ(Encoding);

                if (!string.IsNullOrEmpty(str.TrimEnd('\0')))
                {
                    str = Yakuza0Project.ReadingReplacements(str);

                    value.Original    = str;
                    value.Translation = str;
                    value.Visible     = true;
                }
            }

            s.Seek(pos, SeekOrigin.Begin);

            return(value);
        }
        private DataItem GetDataItem(Stream s, int offset, string section, int length)
        {
            var str = s.ReadStringZ(Encoding);

            if (!string.IsNullOrEmpty(str.TrimEnd('\0')))
            {
                str = Yakuza0Project.ReadingReplacements(str);
            }

            var item = new DataItem
            {
                MaxLength = length,
                Data      = new TFString
                {
                    FileId      = Id,
                    Offset      = offset,
                    Section     = section,
                    Original    = str,
                    Translation = str,
                    Visible     = !string.IsNullOrEmpty(str.TrimEnd('\0'))
                }
            };

            return(item);
        }
Beispiel #4
0
        public override void Save(string fileName, byte[] originalContent, IList <TFString> strings, ExportOptions options)
        {
            using (var fs = new FileStream(fileName, FileMode.Create))
            {
                fs.WriteBytes(_unknown);

                var currentOffset = _unknown.Length + 4 * strings.Count;

                for (var i = 0; i < strings.Count; i++)
                {
                    fs.Seek(_unknown.Length + i * 4, SeekOrigin.Begin);

                    if (strings[i].Offset == 0)
                    {
                        fs.WriteValueS32(0);
                    }
                    else
                    {
                        fs.WriteValueS32(currentOffset, Endianness);

                        fs.Seek(currentOffset, SeekOrigin.Begin);

                        var str = strings[i].Translation;

                        if (!string.IsNullOrEmpty(str))
                        {
                            if (!str.Equals(strings[i].Original))
                            {
                                if (options.CharReplacement != 0)
                                {
                                    str = Utils.ReplaceChars(str, options.CharReplacementList);
                                }

                                str = Yakuza0Project.WritingReplacements(str);

                                fs.WriteStringZ(str, options.SelectedEncoding);

                                currentOffset += str.GetLength(options.SelectedEncoding) + 1;
                            }
                            else
                            {
                                str = Yakuza0Project.WritingReplacements(str);

                                fs.WriteStringZ(str, Encoding);

                                currentOffset += str.GetLength(Encoding) + 1;
                            }
                        }
                        else
                        {
                            // Hay que escribir solo el 0 del final
                            fs.WriteString("\0");
                            currentOffset++;
                        }
                    }
                }
            }
        }
        public override void Save(string fileName, byte[] originalContent, IList <TFString> strings, ExportOptions options)
        {
            File.WriteAllBytes(fileName, originalContent);

            using (var fs = new FileStream(fileName, FileMode.Open))
            {
                for (var i = 0; i < _dataList.Count; i++)
                {
                    var item = _dataList[i];

                    fs.Seek(item.Data.Offset, SeekOrigin.Begin);

                    var tfString = strings.FirstOrDefault(x => x.Offset == item.Data.Offset);

                    if (tfString != null)
                    {
                        string   str;
                        Encoding enc;
                        bool     replaceChars;

                        if (tfString.Original == tfString.Translation)
                        {
                            str          = tfString.Original;
                            enc          = Encoding;
                            replaceChars = false;
                        }
                        else
                        {
                            str          = tfString.Translation;
                            enc          = options.SelectedEncoding;
                            replaceChars = options.CharReplacement != 0;
                        }

                        if (tfString.Visible && !string.IsNullOrEmpty(str))
                        {
                            var zeros = new byte[item.MaxLength];

                            fs.WriteBytes(zeros);

                            if (replaceChars)
                            {
                                str = Utils.ReplaceChars(str, options.CharReplacementList);
                            }

                            str = Yakuza0Project.WritingReplacements(str);

                            if (str.GetLength(enc) >= item.MaxLength)
                            {
                                str = str.Substring(0, item.MaxLength - 1);
                            }

                            fs.Seek(item.Data.Offset, SeekOrigin.Begin);
                            fs.WriteStringZ(str, enc);
                        }
                    }
                }
            }
        }
        public override void Save(string fileName, byte[] originalContent, IList <TFString> strings, ExportOptions options)
        {
            File.WriteAllBytes(fileName, originalContent);

            using (var fs = new FileStream(fileName, FileMode.Open))
            {
                for (var i = 0; i < _dataList.Count; i++)
                {
                    var item = _dataList[i];

                    fs.Seek(item.Offset, SeekOrigin.Begin);

                    string   str;
                    Encoding enc;
                    bool     replace;

                    if (strings[i].Original == strings[i].Translation)
                    {
                        str     = strings[i].Original;
                        enc     = Encoding;
                        replace = false;
                    }
                    else
                    {
                        str     = strings[i].Translation;
                        enc     = options.SelectedEncoding;
                        replace = options.CharReplacement != 0;
                    }

                    if (strings[i].Visible && !string.IsNullOrEmpty(str))
                    {
                        var zeros = new byte[MAX_SIZE];

                        fs.WriteBytes(zeros);

                        if (replace)
                        {
                            str = Utils.ReplaceChars(str, options.CharReplacementList);
                        }

                        str = Yakuza0Project.WritingReplacements(str);

                        if (str.GetLength(enc) >= MAX_SIZE)
                        {
                            str = str.Substring(0, MAX_SIZE - 1);
                        }

                        fs.Seek(item.Offset, SeekOrigin.Begin);
                        fs.WriteStringZ(str, enc);
                    }
                }
            }
        }
Beispiel #7
0
        private void WriteFields(Stream s, IList <TFString> strings, ExportOptions options)
        {
            foreach (var dataField in _dataList)
            {
                s.WriteStringZ(dataField.Name, Encoding);
                var zeros = new byte[48 - (dataField.Name.GetLength(Encoding) + 1)];
                s.WriteBytes(zeros);

                s.WriteValueS32(dataField.DataType, Endianness);
                s.WriteValueS32(dataField.DataCount, Endianness);

                if (dataField.DataType > 0x02)
                {
                    s.WriteValueS32(dataField.DataLength, Endianness);
                }
                else
                {
                    var size = 0;

                    if (dataField.DataRemainder != null)
                    {
                        size += dataField.DataRemainder.Length;
                    }

                    foreach (var tfString in strings.Where(x => x.Section == dataField.Name))
                    {
                        var writeStr = tfString.Translation;
                        if (tfString.Original.Equals(tfString.Translation))
                        {
                            writeStr = Yakuza0Project.WritingReplacements(writeStr);
                            size    += writeStr.GetLength(Encoding) + 1;
                        }
                        else
                        {
                            writeStr = Yakuza0Project.WritingReplacements(writeStr);
                            size    += writeStr.GetLength(options.SelectedEncoding) + 1;
                        }
                    }

                    if (dataField.DataType == 0x02)
                    {
                        size += 2 * dataField.DataCount;
                    }

                    s.WriteValueS32(size, Endianness);
                }
                s.WriteValueS32(0);
            }
        }
        public static Project GetProject(string projectPath)
        {
            if (projectPath.EndsWith("tf_yak0"))
            {
                return(Yakuza0Project.GetProject(projectPath));
            }

            if (projectPath.EndsWith("tf_shm"))
            {
                return(ShenmueProject.GetProject(projectPath));
            }

            if (projectPath.EndsWith("tf_sao_hf"))
            {
                return(SAOProject.GetProject(projectPath));
            }

            if (projectPath.EndsWith("tf_srr"))
            {
                return(SRRProject.GetProject(projectPath));
            }

            if (projectPath.EndsWith("tf_dsg"))
            {
                return(DisgaeaProject.GetProject(projectPath));
            }

            if (projectPath.EndsWith("tf_btr"))
            {
                return(BattleRealmsProject.GetProject(projectPath));
            }

            if (projectPath.EndsWith("tf_spf2"))
            {
                return(Spellforce2Project.GetProject(projectPath));
            }

            if (projectPath.EndsWith("tf_jjm"))
            {
                return(JJMacfieldProject.GetProject(projectPath));
            }

            if (projectPath.EndsWith("tf_nightcry"))
            {
                return(NightCryProject.GetProject(projectPath));
            }

            throw new Exception();
        }
        private int WriteString(Stream s, int offset, TFString item, IList <TFString> strings, ExportOptions options)
        {
            var pos = s.Position;

            var result = offset;

            var tfString = strings.FirstOrDefault(x => x.Offset == item.Offset);

            s.Seek(offset, SeekOrigin.Begin);

            var str = tfString.Translation;

            if (!string.IsNullOrEmpty(str))
            {
                if (!str.Equals(tfString.Original))
                {
                    if (options.CharReplacement != 0)
                    {
                        str = Utils.ReplaceChars(str, options.CharReplacementList);
                    }

                    str = Yakuza0Project.WritingReplacements(str);

                    s.WriteStringZ(str, options.SelectedEncoding);

                    result += str.GetLength(options.SelectedEncoding) + 1;
                }
                else
                {
                    str = Yakuza0Project.WritingReplacements(str);

                    s.WriteStringZ(str, Encoding);

                    result += str.GetLength(Encoding) + 1;
                }
            }
            else
            {
                // Hay que escribir solo el 0 del final
                s.WriteString("\0");
                result++;
            }

            s.Seek(pos, SeekOrigin.Begin);
            return(result);
        }
        private int WriteString(Stream s, int offset, TFString tfString, ExportOptions options, bool writeZero)
        {
            var result = offset;

            s.Seek(offset, SeekOrigin.Begin);

            string   str;
            Encoding enc;
            bool     replaceChars;

            if (tfString.Original == tfString.Translation)
            {
                str          = tfString.Original;
                enc          = Encoding;
                replaceChars = false;
            }
            else
            {
                str          = tfString.Translation;
                enc          = options.SelectedEncoding;
                replaceChars = options.CharReplacement != 0;
            }

            if (!string.IsNullOrEmpty(str))
            {
                if (replaceChars)
                {
                    str = Utils.ReplaceChars(str, options.CharReplacementList);
                }

                str = Yakuza0Project.WritingReplacements(str);

                s.WriteStringZ(str, enc);
                result += str.GetLength(enc) + 1;

                if (writeZero)
                {
                    s.WriteByte(0);
                    result++;
                }
            }

            return(result);
        }
        private TFString ReadString(Stream s, int stringOffset)
        {
            var value = new TFString {
                FileId = Id, Offset = stringOffset, Visible = false
            };

            var str = s.ReadStringZ(Encoding);

            if (!string.IsNullOrEmpty(str.TrimEnd('\0')))
            {
                str = Yakuza0Project.ReadingReplacements(str);

                value.Original    = str;
                value.Translation = str;
                value.Visible     = true;
            }

            return(value);
        }
Beispiel #12
0
        private TFString GetString(Stream s, string section)
        {
            var pos = s.Position;
            var str = s.ReadStringZ(Encoding);

            str = Yakuza0Project.ReadingReplacements(str);

            var tfString = new TFString
            {
                FileId      = Id,
                Original    = str,
                Translation = str,
                Offset      = (int)pos,
                Section     = section,
                Visible     = !string.IsNullOrWhiteSpace(str),
            };

            return(tfString);
        }
Beispiel #13
0
        private void WriteString(Stream s, TFString str, ExportOptions options)
        {
            var writeStr = str.Translation;

            if (str.Original.Equals(str.Translation))
            {
                writeStr = Yakuza0Project.WritingReplacements(writeStr);
                s.WriteStringZ(writeStr, Encoding);
            }
            else
            {
                if (options.CharReplacement != 0)
                {
                    writeStr = Utils.ReplaceChars(writeStr, options.CharReplacementList);
                }

                writeStr = Yakuza0Project.WritingReplacements(writeStr);
                s.WriteStringZ(writeStr, options.SelectedEncoding);
            }
        }
Beispiel #14
0
        private void WriteString(Stream s, string str, ExportOptions options, bool isOriginal)
        {
            if (isOriginal)
            {
                str = Yakuza0Project.WritingReplacements(str);

                s.WriteStringZ(str, Encoding);
            }
            else
            {
                var aux = str;
                if (options.CharReplacement != 0)
                {
                    aux = Utils.ReplaceChars(aux, options.CharReplacementList);
                }

                aux = Yakuza0Project.WritingReplacements(aux);

                s.WriteStringZ(aux, options.SelectedEncoding);
            }
        }
Beispiel #15
0
        private void WriteString(Stream s, TFString tfString, ExportOptions options)
        {
            var pos   = s.Position;
            var zeros = new byte[64];

            s.WriteBytes(zeros);
            s.Seek(pos, SeekOrigin.Begin);

            string   str;
            Encoding enc;
            bool     replace;

            if (tfString.Original == tfString.Translation)
            {
                str     = tfString.Original;
                enc     = Encoding;
                replace = false;
            }
            else
            {
                str     = tfString.Translation;
                enc     = options.SelectedEncoding;
                replace = options.CharReplacement != 0;
            }
            if (replace)
            {
                str = Utils.ReplaceChars(str, options.CharReplacementList);
            }
            str = Yakuza0Project.WritingReplacements(str);

            if (str.GetLength(options.SelectedEncoding) >= 64)
            {
                str = str.Substring(0, 63);
            }

            s.WriteStringZ(str, enc);

            s.Seek(pos + 64, SeekOrigin.Begin);
        }
Beispiel #16
0
        private void WriteString(Stream s, TFString str, ExportOptions options)
        {
            if (str.Original == str.Translation)
            {
                var aux = str.Original;

                aux = Yakuza0Project.WritingReplacements(aux);

                s.WriteStringZ(aux, Encoding);
            }
            else
            {
                var aux = str.Translation;
                if (options.CharReplacement != 0)
                {
                    aux = Utils.ReplaceChars(aux, options.CharReplacementList);
                }

                aux = Yakuza0Project.WritingReplacements(aux);

                s.WriteStringZ(aux, options.SelectedEncoding);
            }
        }
        private void WriteDataItems(Stream s, IList <TFString> strings, ExportOptions options)
        {
            var strCount = _dataList.Sum(x => x.DataCount);

            var offset  = 8 + _dataList.Count * 8; // Primer valor de la primera indireccion
            var offset2 = offset + strCount * 4;   // Primer valor de la segunda indireccion

            var stringIndex = 0;

            foreach (var item in _dataList)
            {
                var pos = s.Position;

                s.WriteValueS32(item.DataCount, Endianness);
                s.WriteValueS32(offset, Endianness);

                s.Seek(offset, SeekOrigin.Begin);

                for (var i = 0; i < item.DataCount; i++)
                {
                    if (item.Data[i].Offset == 0)
                    {
                        s.WriteValueS32(0, Endianness);
                    }
                    else
                    {
                        s.WriteValueS32(offset2, Endianness);
                        s.Seek(offset2, SeekOrigin.Begin);

                        var str = strings[stringIndex].Translation;

                        if (!string.IsNullOrEmpty(str))
                        {
                            if (!str.Equals(strings[stringIndex].Original))
                            {
                                if (options.CharReplacement != 0)
                                {
                                    str = Utils.ReplaceChars(str, options.CharReplacementList);
                                }

                                str = Yakuza0Project.WritingReplacements(str);

                                s.WriteStringZ(str, options.SelectedEncoding);

                                offset2 += str.GetLength(options.SelectedEncoding) + 1;
                            }
                            else
                            {
                                str = Yakuza0Project.WritingReplacements(str);

                                s.WriteStringZ(str, Encoding);

                                offset2 += str.GetLength(Encoding) + 1;
                            }
                        }
                        else
                        {
                            // Hay que escribir solo el 0 del final
                            s.WriteString("\0");
                            offset2++;
                        }
                    }

                    s.Seek(offset + (i + 1) * 4, SeekOrigin.Begin);
                    stringIndex++;
                }

                offset = offset + item.DataCount * 4;
                s.Seek(pos + 8, SeekOrigin.Begin);
            }
        }
        public override void Read(Stream s)
        {
            s.Seek(0x20, SeekOrigin.Begin);

            var titlePointer       = s.ReadValueS32(Endianness);
            var descriptionPointer = s.ReadValueS32(Endianness);

            s.Seek(0x40, SeekOrigin.Begin);

            var ddsPointer = s.ReadValueS32(Endianness);

            if (titlePointer != 0)
            {
                s.Seek(titlePointer, SeekOrigin.Begin);

                var str = s.ReadStringZ(Encoding);
                if (!string.IsNullOrEmpty(str.TrimEnd('\0')))
                {
                    str = Yakuza0Project.ReadingReplacements(str);
                }

                var item = new TFString
                {
                    FileId      = Id,
                    Offset      = titlePointer,
                    Section     = "32",
                    Original    = str,
                    Translation = str,
                    Visible     = !string.IsNullOrEmpty(str.TrimEnd('\0'))
                };

                _title = item;
            }

            if (descriptionPointer != 0)
            {
                s.Seek(descriptionPointer, SeekOrigin.Begin);

                var str = s.ReadStringZ(Encoding);
                if (!string.IsNullOrEmpty(str.TrimEnd('\0')))
                {
                    str = Yakuza0Project.ReadingReplacements(str);
                }

                var item = new TFString
                {
                    FileId      = Id,
                    Offset      = descriptionPointer,
                    Section     = "36",
                    Original    = str,
                    Translation = str,
                    Visible     = !string.IsNullOrEmpty(str.TrimEnd('\0'))
                };

                _description = item;
            }

            if (ddsPointer != 0)
            {
                s.Seek(ddsPointer, SeekOrigin.Begin);

                var str = s.ReadStringZ(Encoding);
                if (!string.IsNullOrEmpty(str.TrimEnd('\0')))
                {
                    str = Yakuza0Project.ReadingReplacements(str);
                }

                var item = new TFString
                {
                    FileId      = Id,
                    Offset      = ddsPointer,
                    Section     = "64",
                    Original    = str,
                    Translation = str,
                    Visible     = false
                };

                _dds = item;
            }
        }
        public override void Save(string fileName, byte[] originalContent, IList <TFString> strings, ExportOptions options)
        {
            using (var fs = new FileStream(fileName, FileMode.Create))
            {
                fs.WriteValueS32(_unknown1, Endianness);
                fs.WriteValueS16(_unknown2, Endianness);
                fs.WriteValueS16(_num, Endianness);
                fs.WriteValueS32(_unknown3, Endianness);
                fs.WriteValueS32(_table2Offset, Endianness);

                var r2Size = 0;
                if (_remainder2 != null)
                {
                    r2Size = _remainder2.Length;
                }

                var currentOffset = 16 + _dataList1.Count * 4 + _remainder1.Length + _dataList2.Count * 48 + r2Size;

                for (var i = 0; i < _dataList1.Count; i++)
                {
                    var item = _dataList1[i];

                    fs.Seek(16 + i * 4, SeekOrigin.Begin);
                    if (item.Offset == 0)
                    {
                        fs.WriteValueS32(0);
                    }
                    else
                    {
                        var tfString = strings.FirstOrDefault(x => x.Offset == item.Offset);
                        fs.WriteValueS32(currentOffset, Endianness);

                        fs.Seek(currentOffset, SeekOrigin.Begin);

                        var str = tfString.Translation;

                        if (!string.IsNullOrEmpty(str))
                        {
                            if (!str.Equals(tfString.Original))
                            {
                                if (options.CharReplacement != 0)
                                {
                                    str = Utils.ReplaceChars(str, options.CharReplacementList);
                                }

                                str = Yakuza0Project.WritingReplacements(str);

                                fs.WriteStringZ(str, options.SelectedEncoding);

                                currentOffset += str.GetLength(options.SelectedEncoding) + 1;
                            }
                            else
                            {
                                str = Yakuza0Project.WritingReplacements(str);

                                fs.WriteStringZ(str, Encoding);

                                currentOffset += str.GetLength(Encoding) + 1;
                            }
                        }
                        else
                        {
                            // Hay que escribir solo el 0 del final
                            fs.WriteString("\0");
                            currentOffset++;
                        }
                    }
                }

                fs.Seek(16 + _dataList1.Count * 4, SeekOrigin.Begin);
                fs.WriteBytes(_remainder1);

                for (var i = 0; i < _dataList2.Count; i++)
                {
                    var item = _dataList2[i];

                    fs.Seek(_table2Offset + i * 48, SeekOrigin.Begin);

                    for (var j = 0; j < 8; j++)
                    {
                        fs.WriteValueS32(item.Unknown[j], Endianness);
                    }
                    fs.WriteValueS32(currentOffset, Endianness);
                    for (var j = 9; j < 12; j++)
                    {
                        fs.WriteValueS32(item.Unknown[j], Endianness);
                    }

                    var tfString = strings.FirstOrDefault(x => x.Offset == item.Data.Offset);

                    fs.Seek(currentOffset, SeekOrigin.Begin);

                    var str = tfString.Translation;

                    if (!string.IsNullOrEmpty(str))
                    {
                        if (!str.Equals(tfString.Original))
                        {
                            if (options.CharReplacement != 0)
                            {
                                str = Utils.ReplaceChars(str, options.CharReplacementList);
                            }

                            str = Yakuza0Project.WritingReplacements(str);

                            fs.WriteStringZ(str, options.SelectedEncoding);

                            currentOffset += str.GetLength(options.SelectedEncoding) + 1;
                        }
                        else
                        {
                            str = Yakuza0Project.WritingReplacements(str);

                            fs.WriteStringZ(str, Encoding);

                            currentOffset += str.GetLength(Encoding) + 1;
                        }
                    }
                    else
                    {
                        // Hay que escribir solo el 0 del final
                        fs.WriteString("\0");
                        currentOffset++;
                    }
                }

                if (_remainder2 != null)
                {
                    fs.Seek(_table2Offset + _num * 48, SeekOrigin.Begin);
                    fs.WriteBytes(_remainder2);
                }
            }
        }
        private void WriteDataItems(Stream s, IList <TFString> strings, ExportOptions options)
        {
            var written = new Dictionary <int, long>();

            var stringOffset = 0x0E03E800;

            foreach (var tfString in strings)
            {
                var indexOffset = Convert.ToInt32(tfString.Section, 16);

                s.Seek(indexOffset, SeekOrigin.Begin);

                if (written.ContainsKey(tfString.Offset))
                {
                    s.WriteValueS64(written[tfString.Offset], Endianness);
                }
                else
                {
                    var correctedOffset = stringOffset + OUTPUT_BASE;

                    s.WriteValueS64(correctedOffset, Endianness);

                    s.Seek(stringOffset, SeekOrigin.Begin);

                    string   str;
                    Encoding enc;
                    bool     replaceChars;

                    if (tfString.Original == tfString.Translation)
                    {
                        str          = tfString.Original;
                        enc          = Encoding;
                        replaceChars = false;
                    }
                    else
                    {
                        str          = tfString.Translation;
                        enc          = options.SelectedEncoding;
                        replaceChars = options.CharReplacement != 0;
                    }

                    if (!string.IsNullOrEmpty(str))
                    {
                        if (replaceChars)
                        {
                            str = Utils.ReplaceChars(str, options.CharReplacementList);
                        }

                        str = Yakuza0Project.WritingReplacements(str);

                        s.WriteStringZ(str, enc);

                        stringOffset += str.GetLength(enc) + 1;
                    }
                    else
                    {
                        // Hay que escribir solo el 0 del final
                        s.WriteString("\0");
                        stringOffset++;
                    }

                    written.Add(tfString.Offset, correctedOffset);
                }
            }
        }
Beispiel #21
0
        public override void Save(string fileName, byte[] originalContent, IList <TFString> strings, ExportOptions options)
        {
            using (var fs = new FileStream(fileName, FileMode.Create))
            {
                fs.WriteBytes(_unknown);

                var currentOffset = _unknown.Length + 16 * strings.Count;

                for (var i = 0; i < _dataList.Count; i++)
                {
                    var item = _dataList[i];

                    fs.Seek(_unknown.Length + i * 16, SeekOrigin.Begin);

                    fs.WriteBytes(item.Unknown);

                    fs.WriteValueS32(currentOffset, Endianness);

                    var posAux = fs.Position;

                    fs.Seek(currentOffset, SeekOrigin.Begin);

                    var tfString = strings.FirstOrDefault(x => x.Offset == item.Data.Offset);

                    if (tfString != null)
                    {
                        var str = tfString.Translation;

                        if (!string.IsNullOrEmpty(str))
                        {
                            if (!str.Equals(tfString.Original))
                            {
                                if (options.CharReplacement != 0)
                                {
                                    str = Utils.ReplaceChars(str, options.CharReplacementList);
                                }

                                str = Yakuza0Project.WritingReplacements(str);

                                fs.WriteStringZ(str, options.SelectedEncoding);

                                currentOffset += str.GetLength(options.SelectedEncoding) + 1;
                            }
                            else
                            {
                                str = Yakuza0Project.WritingReplacements(str);

                                fs.WriteStringZ(str, Encoding);

                                currentOffset += str.GetLength(Encoding) + 1;
                            }
                        }
                        else
                        {
                            // Hay que escribir solo el 0 del final
                            fs.WriteString("\0");
                            currentOffset++;
                        }
                    }

                    fs.Seek(posAux, SeekOrigin.Begin);
                    fs.WriteValueS32(currentOffset, Endianness);
                    fs.Seek(currentOffset, SeekOrigin.Begin);

                    fs.WriteBytes(item.Remainder);
                    currentOffset += item.Remainder.Length;
                }
            }
        }
        public override void Save(string fileName, byte[] originalContent, IList <TFString> strings, ExportOptions options)
        {
            using (var fs = new FileStream(fileName, FileMode.Create))
            {
                var header = new byte[0x174];
                Array.Copy(originalContent, header, 0x174);
                fs.WriteBytes(header);

                var remainder = new byte[4200];
                var originalRemainderOffset = (originalContent[0x28] << 24) + (originalContent[0x29] << 16) +
                                              (originalContent[0x2A] << 8) + originalContent[0x2B];

                Array.Copy(originalContent, originalRemainderOffset, remainder, 0, 4200);

                var stringOffsets = new List <int>();

                for (var i = 0; i < strings.Count; i++)
                {
                    stringOffsets.Add((int)fs.Position);
                    var str = strings[i].Translation;

                    if (!string.IsNullOrEmpty(str))
                    {
                        if (!str.Equals(strings[i].Original))
                        {
                            if (options.CharReplacement != 0)
                            {
                                str = Utils.ReplaceChars(str, options.CharReplacementList);
                            }

                            str = Yakuza0Project.WritingReplacements(str);

                            fs.WriteStringZ(str, options.SelectedEncoding);
                        }
                        else
                        {
                            str = Yakuza0Project.WritingReplacements(str);

                            fs.WriteStringZ(str, Encoding);
                        }
                    }
                    else
                    {
                        // Hay que escribir solo el 0 del final
                        fs.WriteString("\0");
                    }
                }

                while (fs.Position % 16 != 0)
                {
                    fs.WriteByte(0);
                }

                var offsetsPointer = fs.Position;

                foreach (var offset in stringOffsets)
                {
                    fs.WriteValueS32(offset, Endianness);
                }

                var remainderPointer = fs.Position;
                fs.WriteBytes(remainder);

                fs.Seek(-4, SeekOrigin.Current);
                var lastPointer = fs.Position;
                fs.WriteValueS32((int)(remainderPointer + 8), Endianness);

                while (fs.Position % 16 != 0)
                {
                    fs.WriteByte(0);
                }

                var totalLength = fs.Position;

                fs.Seek(0x0C, SeekOrigin.Begin);
                fs.WriteValueS32((int)totalLength, Endianness);

                fs.Seek(0x28, SeekOrigin.Begin);
                fs.WriteValueS32((int)remainderPointer, Endianness);
                fs.WriteValueS32((int)lastPointer, Endianness);

                fs.Seek(0x34, SeekOrigin.Begin);
                fs.WriteValueS32((int)(remainderPointer + 4), Endianness);
                fs.WriteValueS32((int)offsetsPointer, Endianness);
            }
        }
        public override void Save(string fileName, byte[] originalContent, IList <TFString> strings,
                                  ExportOptions options)
        {
            using (var fs = new FileStream(fileName, FileMode.Create))
            {
                foreach (var section in _sections)
                {
                    var offsetPos = fs.Position;
                    fs.WriteValueS16(0, Endianness);
                    fs.WriteStringZ(section.Name, Encoding);

                    foreach (var itemData in section.Strings)
                    {
                        fs.WriteValueU8(itemData.Index);

                        var tfString = strings.FirstOrDefault(x => x.Offset == itemData.Data.Offset);

                        string   str;
                        Encoding enc;
                        bool     replaceChars;

                        if (tfString.Original == tfString.Translation)
                        {
                            str          = tfString.Original;
                            enc          = Encoding;
                            replaceChars = false;
                        }
                        else
                        {
                            str          = tfString.Translation;
                            enc          = options.SelectedEncoding;
                            replaceChars = options.CharReplacement != 0;
                        }

                        if (!string.IsNullOrEmpty(str))
                        {
                            if (replaceChars)
                            {
                                str = Utils.ReplaceChars(str, options.CharReplacementList);
                            }

                            str = Yakuza0Project.WritingReplacements(str);

                            var length = str.GetLength(enc);
                            fs.WriteValueU8((byte)length);
                            fs.WriteStringZ(str, enc);
                        }
                        else
                        {
                            // Hay que escribir solo el 0 del final
                            fs.WriteValueU8(0); // longitud
                            fs.WriteValueU8(0); // cadena
                        }
                    }

                    fs.WriteValueS16(-1, Endianness);

                    var pos = fs.Position;
                    fs.Seek(offsetPos, SeekOrigin.Begin);
                    fs.WriteValueS16((short)pos, Endianness);
                    fs.Seek(pos, SeekOrigin.Begin);
                }
            }
        }