/// <summary> /// Inserts the text strings back into the game file. /// </summary> /// <returns>A value indicating whether the file was successfully saved.</returns> protected override bool SaveText() { byte[] fileData = StreamHelper.ReadFile(this.GameFileName); int linesAdded = 0; Dictionary <string, int> dupes = new Dictionary <string, int>(); List <ScriptPointer> scriptPointers = new List <ScriptPointer>(this.strings.Length); int i; for (i = 0; i < this.strings.Length; i++) { ScriptPointer scriptPointer = new ScriptPointer(this.Game, this.pointers[i], this.strings[i]); scriptPointers.Add(scriptPointer); } List <TextRange> textRanges = new List <TextRange>(this.validTextRanges); scriptPointers.Sort(); textRanges.Sort(); /* * System.Diagnostics.Debug.WriteLine("Phase 1"); * for (int a = 0; a < scriptPointers.Count; a++) * { * if (scriptPointers[a] == null) continue; * System.Diagnostics.Debug.WriteLine(a + ". " + scriptPointers[a].Length + " - " + scriptPointers[a].Text); * } * for (int b = 0; b < textRanges.Count; b++) * { * if (textRanges[b] == null) continue; * System.Diagnostics.Debug.WriteLine(b + ". " + textRanges[b].Length); * } */ i = 0; int k = 0; byte[] pointerBytes; while (i < scriptPointers.Count) { if (dupes.ContainsKey(scriptPointers[i].Text)) { ////System.Diagnostics.Debug.WriteLine("Skipping duplicate line " + i + "."); pointerBytes = BitConverter.GetBytes(dupes[scriptPointers[i].Text]); Array.Copy(pointerBytes, 0, fileData, scriptPointers[i].Pointer, Constants.PointerLength); scriptPointers[i] = null; linesAdded++; i++; } else if (k < textRanges.Count) { if (scriptPointers[i].Length > textRanges[k].Length) { ////System.Diagnostics.Debug.WriteLine("Line " + i + " is larger than current range, skipping."); i++; } else if (scriptPointers[i].Length < textRanges[k].Length) { ////System.Diagnostics.Debug.WriteLine("Range " + k + " is larger than current line, skipping."); k++; } else { ////System.Diagnostics.Debug.WriteLine("Writing line " + i + " to range " + k + ". New length = 0"); int textOffset = textRanges[k].Start; textRanges[k] = null; k++; byte[] encodedText = scriptPointers[i].GetEncodedText(); Array.Copy(encodedText, 0, fileData, textOffset, encodedText.Length); for (int pad = encodedText.Length; pad < scriptPointers[i].Length; pad++) { fileData[textOffset + pad] = 0x00; } pointerBytes = BitConverter.GetBytes(textOffset + this.overlayOffset); Array.Copy(pointerBytes, 0, fileData, scriptPointers[i].Pointer, Constants.PointerLength); dupes.Add(scriptPointers[i].Text, textOffset + this.overlayOffset); scriptPointers[i] = null; linesAdded++; i++; } } else { ////System.Diagnostics.Debug.WriteLine("Line " + i + " is larger than current range, skipping."); i++; } } /* * System.Diagnostics.Debug.WriteLine("Phase 2"); * for (int a = 0; a < scriptPointers.Count; a++) * { * if (scriptPointers[a] == null) continue; * System.Diagnostics.Debug.WriteLine(a + ". " + scriptPointers[a].Length + " - " + scriptPointers[a].Text); * } * for (int b = 0; b < textRanges.Count; b++) * { * if (textRanges[b] == null) continue; * System.Diagnostics.Debug.WriteLine(b + ". " + textRanges[b].Length); * } */ for (i = 0; i < scriptPointers.Count; i++) { if (scriptPointers[i] == null) { continue; } if (dupes.ContainsKey(scriptPointers[i].Text)) { ////System.Diagnostics.Debug.WriteLine("Skipping duplicate line " + i + "."); pointerBytes = BitConverter.GetBytes(dupes[scriptPointers[i].Text]); } else { int textOffset = -1; for (k = 0; k < textRanges.Count; k++) { if (textRanges[k] == null) { ////System.Diagnostics.Debug.WriteLine("No room for line " + i + "."); continue; } if (scriptPointers[i].Length <= textRanges[k].Length) { textOffset = textRanges[k].Start; textRanges[k].Start = textOffset + scriptPointers[i].Length; ////System.Diagnostics.Debug.WriteLine("Writing line " + i + " to range " + k + ". New start = " + textRanges[k].Start + ", new length = " + textRanges[k].Length); if (textRanges[k].Length == 0) { textRanges[k] = null; } break; } } if (textOffset == -1) { continue; } byte[] encodedText = scriptPointers[i].GetEncodedText(); Array.Copy(encodedText, 0, fileData, textOffset, encodedText.Length); for (int pad = encodedText.Length; pad < scriptPointers[i].Length; pad++) { fileData[textOffset + pad] = 0x00; } pointerBytes = BitConverter.GetBytes(textOffset + this.overlayOffset); dupes.Add(scriptPointers[i].Text, textOffset + this.overlayOffset); } Array.Copy(pointerBytes, 0, fileData, scriptPointers[i].Pointer, Constants.PointerLength); linesAdded++; } if (linesAdded < scriptPointers.Count) { string message = string.Format(CultureInfo.CurrentCulture, "Ran out of room for translated text! (lines fit {0}/{1})", linesAdded, scriptPointers.Count); throw new FormatException(message); } StreamHelper.WriteFile(this.GameFileName, fileData); return(true); }
/// <summary> /// Compares the lengths of the two lines once they have been encoded. /// </summary> /// <param name="obj">The line to compare to this.</param> /// <returns>Positive if this line is shorter than that one, negative if it is longer, or zero if they have equal length.</returns> public int CompareTo(object obj) { ScriptPointer that = (ScriptPointer)obj; return(that.length.CompareTo(this.length)); }