/// <summary> /// Repacks all files into the pack. /// </summary> public void Pack() { byte[] fileData = StreamHelper.ReadFile(this.DecompressedFileName); fileData = CompressionManager.CompressOverlay(fileData); StreamHelper.WriteFile(this.CompressedFileName, fileData); this.CompressedFileSize = fileData.Length; }
/// <summary> /// Unpacks and initializes all files from the pack. /// </summary> public void Unpack() { byte[] fileData = StreamHelper.ReadFile(this.CompressedFileName); fileData = CompressionManager.DecompressOverlay(fileData); StreamHelper.WriteFile(this.DecompressedFileName, fileData); this.InitializeChildren(); }
/// <summary> /// Repacks all files into the pack. /// </summary> public void Pack() { int headerLength = this.game.Cache.Settings["arm9"]["headerLength"].Int32Value; byte[] footer = DecodeFooter(this.game.Cache.Settings["arm9"]["footer"].Value); byte[] fileData = StreamHelper.ReadFile(this.DecompressedFileName); fileData = CompressionManager.CompressArm9(fileData, headerLength, footer); StreamHelper.WriteFile(this.CompressedFileName, fileData); }
/// <summary> /// Unpacks and initializes all files from the pack. /// </summary> public void Unpack() { int headerLength; byte[] footer; this.textFiles.Clear(); byte[] fileData = StreamHelper.ReadFile(this.CompressedFileName); fileData = CompressionManager.DecompressArm9(fileData, out headerLength, out footer); StreamHelper.WriteFile(this.DecompressedFileName, fileData); this.game.Cache.Settings["arm9"]["headerLength"].Int32Value = headerLength; this.game.Cache.Settings["arm9"]["footer"].Value = EncodeFooter(footer); this.InitializeChildren(); }
/// <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); }