/// <summary> /// Save a list of TLKStringRefs to a TLK file. /// </summary> /// <param name="outfile"></param> /// <param name="stringRefs"></param> internal static void SaveToTlkFile(string outfile, List <TalkFileME1.TLKStringRef> stringRefs) { HuffmanCompressionME2ME3 huff = new HuffmanCompressionME2ME3(); //load data int position = 0; foreach (var sref in stringRefs) { var data = sref.Data == null ? null : sref.Data.Replace("\r\n", "\n"); /* every string should be NULL-terminated */ if (sref.StringID >= 0) { data += '\0'; } /* only add debug info if we are in debug mode and StringID is positive AND it's localizable */ huff._inputData.Add(new TLKEntry(sref.StringID, position, data)); position++; } huff._inputData.Sort(); huff.PrepareHuffmanCoding(); huff.SaveToTlkFile(outfile); }
/// <summary> /// Dumps data from memory to TLK compressed file format. /// <remarks> /// Compressed data should be read into memory first, by LoadInputData method. /// </remarks> /// </summary> /// <param name="fileName"></param> public static void SaveToTlkFile(string fileName, List <TLKStringRef> stringRefs = null) { HuffmanCompressionME2ME3 hc = new HuffmanCompressionME2ME3(); File.Delete(fileName); if (stringRefs != null) { hc._inputData = stringRefs.OrderBy(x => x.CalculatedStringID).ToList(); hc.PrepareHuffmanCoding(); } /* converts Huffmann Tree to binary form */ List <int> treeBuffer = hc.ConvertHuffmanTreeToBuffer(); /* preparing data and entries for writing to file * entries list consists of pairs <String ID, Offset> */ List <BitArray> binaryData = new List <BitArray>(); Dictionary <int, int> maleStrings = new Dictionary <int, int>(); Dictionary <int, int> femaleStrings = new Dictionary <int, int>(); int offset = 0; foreach (var entry in hc._inputData) { if (entry.StringID < 0) { if (!maleStrings.ContainsKey(entry.StringID)) { maleStrings.Add(entry.StringID, Convert.ToInt32(entry.ASCIIData)); } else { femaleStrings.Add(entry.StringID, Convert.ToInt32(entry.ASCIIData)); } continue; } if (!maleStrings.ContainsKey(entry.StringID)) { maleStrings.Add(entry.StringID, offset); } else { femaleStrings.Add(entry.StringID, offset); } /* for every character in a string, put it's binary code into data array */ foreach (char c in entry.ASCIIData) { binaryData.Add(hc._huffmanCodes[c]); offset += hc._huffmanCodes[c].Count; } } /* preparing TLK Header */ int magic = 7040084; int ver = 3; int min_ver = 2; int entry1Count = maleStrings.Count; int entry2Count = femaleStrings.Count; int treeNodeCount = treeBuffer.Count() / 2; int dataLength = offset / 8; if (offset % 8 > 0) { ++dataLength; } BinaryWriter bw = new BinaryWriter(File.OpenWrite(fileName)); /* writing TLK Header */ bw.Write(magic); bw.Write(ver); bw.Write(min_ver); bw.Write(entry1Count); bw.Write(entry2Count); bw.Write(treeNodeCount); bw.Write(dataLength); /* writing entries */ foreach (var entry in maleStrings) { bw.Write(entry.Key); bw.Write(entry.Value); } foreach (var entry in femaleStrings) { bw.Write(entry.Key); bw.Write(entry.Value); } /* writing HuffmanTree */ foreach (int element in treeBuffer) { bw.Write(element); } /* writing data */ byte[] data = BitArrayListToByteArray(binaryData, offset); bw.Write(data); bw.Close(); }