/// <summary> /// Reads in the replacement text strings from the text file. /// </summary> /// <returns>A value indicating whether the file was successfully imported.</returns> protected override bool ImportText() { StreamHelper.ReadLinesFromFile(this.TextFileName, this.strings, this.Game.Encoding); return(true); }
/* * /// <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); * * Dictionary<string, int> dupes = new Dictionary<string, int>(); * * KeyValuePair<int, int>[] textRanges = new KeyValuePair<int, int>[this.validTextRanges.Length]; * for (int i = 0; i < textRanges.Length; i++) * { * textRanges[i] = this.validTextRanges[i]; * } * * byte[] pointerBytes; * for (int i = 0; i < this.pointers.Length; i++) * { * if (dupes.ContainsKey(this.strings[i])) * { * pointerBytes = BitConverter.GetBytes(dupes[this.strings[i]]); * } * else * { * byte[] encodedString = this.Game.GetBytes(this.strings[i]); * int textLength = encodedString.Length + 1; * while (textLength % 4 != 0) * { * textLength++; * } * * int textOffset = -1; * for (int k = 0; k < textRanges.Length; k++) * { * int rangeLength = textRanges[k].Value - textRanges[k].Key + 1; * if (textLength <= rangeLength) * { * textOffset = textRanges[k].Key; * textRanges[k] = new KeyValuePair<int, int>(textOffset + textLength, textRanges[k].Value); * break; * } * } * * if (textOffset == -1) * { * string message = string.Format(CultureInfo.CurrentCulture, "Ran out of room for translated text! (line {0}/{1})", i + 1, this.pointers.Length); * throw new FormatException(message); * } * * Array.Copy(encodedString, 0, fileData, textOffset, encodedString.Length); * for (int pad = encodedString.Length; pad < textLength; pad++) * { * fileData[textOffset + pad] = 0x00; * } * * pointerBytes = BitConverter.GetBytes(textOffset + this.overlayOffset); * dupes.Add(this.strings[i], textOffset + this.overlayOffset); * } * * Array.Copy(pointerBytes, 0, fileData, this.pointers[i], Constants.PointerLength); * } * * StreamHelper.WriteFile(this.GameFileName, fileData); * return true; * } */ /// <summary> /// Writes the text strings into an easily editable text file. /// </summary> /// <returns>A value indicating whether the file was successfully exported.</returns> protected override bool ExportText() { StreamHelper.WriteLinesToFile(this.TextFileName, this.strings, this.Game.Encoding); return(true); }
private void ImportListOfValidPointers() { FileStream file = new FileStream(this.TextFileName, FileMode.Open, FileAccess.Read); StreamReader reader = new StreamReader(file, this.game.Encoding); List <int> offsets = new List <int>(); string line = StreamHelper.ReadNextLine(reader); int i = 0; while (line != null && line.Length > 0) { i++; int offset = Convert.ToInt32(line.Substring(0, 8), 16); offsets.Add(offset); line = StreamHelper.ReadNextLine(reader); } reader.Close(); ////======================== byte[] fileData = StreamHelper.ReadFile(this.GameFileName); this.pointerOffsets = offsets.ToArray(); SortedDictionary <int, int> textRanges = new SortedDictionary <int, int>(); for (i = 0; i < this.pointerOffsets.Length; i++) { int key = BitConverter.ToInt32(fileData, this.pointerOffsets[i]) - Arm9Offset; int val = key; for (val = key; fileData[val] != 0x00 || (val % 4) != 3; val++) { } if (!textRanges.ContainsKey(key)) { textRanges.Add(key, val); } } this.validTextRanges = new SortedDictionary <int, int>(); int startOffset = -1; int endOffset = -1; foreach (KeyValuePair <int, int> kvp in textRanges) { if (kvp.Key == endOffset + 1) { endOffset = kvp.Value; } else { if (startOffset != -1) { this.validTextRanges.Add(startOffset, endOffset); } startOffset = kvp.Key; endOffset = kvp.Value; } } this.validTextRanges.Add(startOffset, endOffset); }
/// <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> /// 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() { if (!this.IsModified) { return(false); } byte[] fileData = StreamHelper.ReadFile(this.GameFileName); Dictionary <string, int> dupes = new Dictionary <string, int>(); KeyValuePair <int, int>[] textRanges = new KeyValuePair <int, int> [this.validTextRanges.Length]; for (int i = 0; i < textRanges.Length; i++) { textRanges[i] = this.validTextRanges[i]; } byte[] pointerBytes; for (int i = 0; i < this.pointers.Length; i++) { if (dupes.ContainsKey(this.strings[i])) { pointerBytes = BitConverter.GetBytes(dupes[this.strings[i]]); } else { byte[] encodedString = this.Game.GetBytes(this.strings[i]); int textLength = encodedString.Length + 1; while (textLength % 4 != 0) { textLength++; } int textOffset = -1; for (int k = 0; k < textRanges.Length; k++) { int rangeLength = textRanges[k].Value - textRanges[k].Key + 1; if (textLength <= rangeLength) { textOffset = textRanges[k].Key; textRanges[k] = new KeyValuePair <int, int>(textOffset + textLength, textRanges[k].Value); break; } } if (textOffset == -1) { string message = string.Format(CultureInfo.CurrentCulture, "Ran out of room for translated text! (line {0}/{1})", i + 1, this.pointers.Length); throw new FormatException(message); } Array.Copy(encodedString, 0, fileData, textOffset, encodedString.Length); for (int pad = encodedString.Length; pad < textLength; pad++) { fileData[textOffset + pad] = 0x00; } pointerBytes = BitConverter.GetBytes(textOffset + Arm9Offset); dupes.Add(this.strings[i], textOffset + Arm9Offset); } Array.Copy(pointerBytes, 0, fileData, this.pointers[i], Constants.PointerLength); } StreamHelper.WriteFile(this.GameFileName, fileData); return(true); }