Esempio n. 1
0
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="count">The initial number of entries in the tlk file.</param>
        public Tlk(int count)
        {
            name = string.Empty;
            header = new TlkHeader();
            resRefs = new RawResRef[count];
            strings = new string[count];

            header.fileType = tlkFile;
            header.fileVersion = tlkVersion;
            header.stringCount = count;
            header.stringOffset = 0;

            for (int i = 0; i < count; i++)
            {
                resRefs[i] = new RawResRef();
                resRefs[i].flags = (int) ResRefFlags.None;
                resRefs[i].offsetToString = 0;
                resRefs[i].pitchVariance = 0;
                resRefs[i].soundLength = 0;
                resRefs[i].soundResRef = string.Empty;
                resRefs[i].stringSize = 0;
                resRefs[i].volumeVariance = 0;

                strings[i] = string.Empty;
            }
        }
Esempio n. 2
0
        public void LoadTlkData(string path)
        {
            //var huffman = new StaticHuffman<char>();

            /* **************** STEP ONE ****************
             *          -- load TLK file header --
             *
             * reading first 28 (4 * 7) bytes
             */
            _path = path;
            Stream fs = File.OpenRead(path);
            var    r  = new BinaryReader(fs);

            _header = new TlkHeader(r);

            //DebugTools.PrintHeader(Header);

            /* **************** STEP TWO ****************
             *  -- read and store Huffman Tree nodes --
             */
            /* jumping to the beginning of Huffmann Tree stored in TLK file */
            var pos = r.BaseStream.Position;

            r.BaseStream.Seek(pos + (_header.MaleEntryCount + _header.FemaleEntryCount) * 8, SeekOrigin.Begin);

            _characterTree = new List <HuffmanNode>();
            for (var i = 0; i < _header.TreeNodeCount; i++)
            {
                _characterTree.Add(new HuffmanNode(r));
            }

            r.BaseStream.Seek(pos + (_header.MaleEntryCount + _header.FemaleEntryCount) * 8, SeekOrigin.Begin);
            var characterTree = new List <Tuple <int, int> >();

            //var queue = new Queue<HuffmanNode<int>>();
            //var queue = new Queue<HuffmanNode<int>>();

            for (var i = 0; i < _header.TreeNodeCount; i++)
            {
                characterTree.Add(new Tuple <int, int>(r.ReadInt32(), r.ReadInt32()));
            }

            /*foreach (var tuple in characterTree)
             * {
             *      var leftNode = new HuffmanNode<int>(tuple.Item1);
             *      var rightNode = new HuffmanNode<int>(tuple.Item2);
             *      var parent = new HuffmanNode<int>(leftNode, rightNode);
             *
             *      queue.Enqueue(parent);
             * }*/

            //var tree = new HuffmanTree<int>(table);


            /* **************** STEP THREE ****************
             *  -- read all of coded data into memory --
             */
            var data = new byte[_header.DataLen];

            r.BaseStream.Read(data, 0, data.Length);
            /* and store it as raw bits for further processing */
            _bits = new BitArray(data);

            /* rewind BinaryReader just after the Header
             * at the beginning of TLK Entries data */
            r.BaseStream.Seek(pos, SeekOrigin.Begin);

            /* **************** STEP FOUR ****************
             * -- decode (basing on Huffman Tree) raw bits data into actual strings --
             * and store them in a Dictionary<int, string> where:
             *   int: bit offset of the beginning of data (offset starting at 0 and counted for Bits array)
             *        so offset == 0 means the first bit in Bits array
             *   string: actual decoded string */
            var rawStrings = new Dictionary <int, string>();
            var offset     = 0;

            // int maxOffset = 0;
            while (offset < _bits.Length)
            {
                var key = offset;
                // if (key > maxOffset)
                // maxOffset = key;
                /* read the string and update 'offset' variable to store NEXT string offset */
                var s = GetString(ref offset);
                rawStrings.Add(key, s);
            }
            // Console.WriteLine("Max offset = " + maxOffset);

            /* **************** STEP FIVE ****************
             *         -- bind data to String IDs --
             * go through Entries in TLK file and read it's String ID and offset
             * then check if offset is a key in rawStrings and if it is, then bind data.
             * Sometimes there's no such key, in that case, our String ID is probably a substring
             * of another String present in rawStrings.
             */
            //StringRefs = new XmlTlkStrings();
            MaleStringRefs   = new List <TlkString>();
            FemaleStringRefs = new List <TlkString>();

            for (var i = 0; i < _header.MaleEntryCount /* + _header.FemaleEntryCount*/; i++)
            {
                var sref = new TlkString(r, i);

                if (sref.BitOffset >= 0)
                {
                    if (!rawStrings.ContainsKey(sref.BitOffset))
                    {
                        var tmpOffset  = sref.BitOffset;
                        var partString = GetString(ref tmpOffset);

                        /* actually, it should store the fullString and subStringOffset,
                         * but as we don't have to use this compression feature,
                         * we will store only the part of string we need */

                        /* int key = rawStrings.Keys.Last(c => c < sref.BitOffset);
                         * string fullString = rawStrings[key];
                         * int subStringOffset = fullString.LastIndexOf(partString);
                         * sref.StartOfString = subStringOffset;
                         * sref.Data = fullString;
                         */
                        sref.Value = partString;
                    }
                    else
                    {
                        sref.Value = rawStrings[sref.BitOffset];
                    }
                }

                if (string.IsNullOrEmpty(sref.Value) || string.IsNullOrWhiteSpace(sref.Value))
                {
                    sref.Value = TlkString.EmptyText;
                }

                MaleStringRefs.Add(sref);
            }

            for (var i = 0; i < _header.FemaleEntryCount; i++)
            {
                var sref = new TlkString(r, i);

                if (sref.BitOffset >= 0)
                {
                    if (!rawStrings.ContainsKey(sref.BitOffset))
                    {
                        var tmpOffset  = sref.BitOffset;
                        var partString = GetString(ref tmpOffset);

                        /* actually, it should store the fullString and subStringOffset,
                         * but as we don't have to use this compression feature,
                         * we will store only the part of string we need */

                        /* int key = rawStrings.Keys.Last(c => c < sref.BitOffset);
                         * string fullString = rawStrings[key];
                         * int subStringOffset = fullString.LastIndexOf(partString);
                         * sref.StartOfString = subStringOffset;
                         * sref.Data = fullString;
                         */
                        sref.Value = partString;
                    }
                    else
                    {
                        sref.Value = rawStrings[sref.BitOffset];
                    }
                }

                if (string.IsNullOrEmpty(sref.Value) || string.IsNullOrWhiteSpace(sref.Value))
                {
                    sref.Value = TlkString.EmptyText;
                }

                FemaleStringRefs.Add(sref);
            }

            r.Close();
        }
Esempio n. 3
0
 /// <summary>
 /// Private constructor, instances of this class must
 /// </summary>
 private Tlk()
 {
     header = new TlkHeader();
     resRefs = null;
     strings = null;
 }
Esempio n. 4
0
 /// <summary>
 /// Deserializes the header from the given byte array. 
 /// </summary>
 /// <param name="bytes">The byte array containing the header</param>
 private void DeserializeHeader(byte[] bytes)
 {
     // Alloc a hglobal to store the bytes.
     IntPtr buffer = Marshal.AllocHGlobal(bytes.Length);
     try
     {
         // Copy the data to unprotected memory, then convert it to a TlkHeader
         // structure
         Marshal.Copy(bytes, 0, buffer, bytes.Length);
         object o = Marshal.PtrToStructure(buffer, typeof(TlkHeader));
         header = (TlkHeader) o;
     }
     finally
     {
         // Free the hglobal before exiting.
         Marshal.FreeHGlobal(buffer);
     }
 }