public Z64File ToFile(Z64Game game) { if (!Valid()) { return(new Z64File(null, -1, -1, -1, false)); } if (!Exist()) { return(Z64File.DeletedFile(VRomStart, RomStart, VRomEnd - VRomStart)); } int len = GetSize(); byte[] data = new byte[len]; Buffer.BlockCopy(game.Rom.RawRom, RomStart, data, 0, len); int romEnd = RomStart + data.Length; if (Compressed()) { data = Yaz0.Decompress(data); } return(new Z64File(data, VRomStart, RomStart, romEnd, Compressed())); }
/// <summary> /// Returns a reference to a decompressed file /// </summary> /// <param name="record">The DMA address used to reference the file</param> /// <returns></returns> protected RomFile GetFile(FileRecord record) { MemoryStream ms; byte[] data; byte[] decompressedData; if (record.VirtualAddress == CachedFileAddress) { ms = new MemoryStream(CachedFile); return(new RomFile(record, ms, Version)); } using (FileStream fs = new FileStream(RomLocation, FileMode.Open, FileAccess.Read)) { data = new byte[record.DataAddress.Size]; fs.Position = record.DataAddress.Start; fs.Read(data, 0, (int)record.DataAddress.Size); if (record.IsCompressed) { ms = new MemoryStream(data); decompressedData = Yaz0.Decode(ms, (int)(record.DataAddress.Size)); } else { decompressedData = data; } } CachedFile = decompressedData; ms = new MemoryStream(decompressedData); CachedFileAddress = record.VirtualAddress; return(new RomFile(record, ms, Version)); }
public void Load(string filename) { FileInfo = new FileInfo(filename); using (var br = new BinaryReaderX(FileInfo.OpenRead())) { _sarc = new SARC(new MemoryStream(Yaz0.Decompress(new MemoryStream(br.ReadBytes((int)FileInfo.Length)), ByteOrder.BigEndian))); } }
/// <summary> /// Loads an archive into a <see cref="VirtualFilesystemDirectory"/>, automatically de-compressing the archive if required. /// /// </summary> /// <param name="filePath">Filepath of file to (optionally) decompress and load.</param> /// <returns><see cref="VirtualFilesystemDirectory"/> containing the contents, or null if filepath is not a valid archive.</returns> public static VirtualFilesystemDirectory LoadArchive(string filePath) { if (string.IsNullOrEmpty(filePath)) { throw new ArgumentNullException("filePath", "Cannot load archive from empty file path!"); } if (!File.Exists(filePath)) { throw new ArgumentException("Cannot load archive from non-existant file!", "filePath"); } MemoryStream decompressedFile = null; using (EndianBinaryReader fileReader = new EndianBinaryReader(File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Endian.Big)) { // Read the first 4 bytes to see if it's a compressed file (Yaz0) or a plain RARC file. uint fileMagic = fileReader.ReadUInt32(); fileReader.BaseStream.Position = 0L; // Reset to the start so that the next thing to read it is at the start like it expects. switch (fileMagic) { case 0x59617A30: // Yaz0 Compression decompressedFile = Yaz0.Decode(fileReader); break; case 0x59617930: // Yay0 Compression decompressedFile = Yay0.Decode(fileReader); break; case 0x52415243: // RARC - Uncompressed decompressedFile = new MemoryStream((int)fileReader.BaseStream.Length); fileReader.BaseStream.CopyTo(decompressedFile); // Copying modifies the decompressedFile's read head (places it at new location) so we rewind. decompressedFile.Position = 0L; break; default: throw new NotImplementedException(string.Format("Unknown magic: {0}. If this is a Nintendo archive, open an Issue on GitHub!", fileMagic.ToString("X8"))); } } // Not an archive we know how to handle. if (decompressedFile == null) { return(null); } // Decompress the archive into the folder. It'll generate a sub-folder with the Archive's ROOT name. Archive rarc = new Archive(); using (EndianBinaryReader reader = new EndianBinaryReader(decompressedFile, Endian.Big)) { return(rarc.ReadFile(reader)); } }
private static Tuple <Stream, string> CompressFileFormat(ICompressionFormat compressionFormat, Stream data, bool FileIsCompressed, int Alignment, string FileName, bool EnableDialog = true) { string extension = Path.GetExtension(FileName); if (extension == ".szs" || extension == ".sbfres") { FileIsCompressed = true; compressionFormat = new Yaz0(); } if (compressionFormat == null) { return(Tuple.Create(data, "")); } bool CompressFile = false; if (EnableDialog && FileIsCompressed) { if (Runtime.AlwaysCompressOnSave) { CompressFile = true; } else { DialogResult save = MessageBox.Show($"Compress file with {compressionFormat}?", "File Save", MessageBoxButtons.YesNo); CompressFile = (save == DialogResult.Yes); } } else if (FileIsCompressed) { CompressFile = true; } Console.WriteLine($"FileIsCompressed {FileIsCompressed} CompressFile {CompressFile} CompressionType {compressionFormat}"); if (CompressFile) { if (compressionFormat is Yaz0) { ((Yaz0)compressionFormat).Alignment = Alignment; } System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); var comp = compressionFormat.Compress(data); sw.Stop(); TimeSpan ts = sw.Elapsed; string message = string.Format("{0:D2}:{1:D2}:{2:D2}", ts.Minutes, ts.Seconds, ts.Milliseconds); Console.WriteLine($"Compression Time : {message}"); return(Tuple.Create(comp, message)); } return(Tuple.Create(data, "")); }
static void Main(string[] args) { String file = args[0]; byte[] uncompressed = Yaz0.Decompress(file); String output = Path.GetDirectoryName(file) + "test.notyaz0"; File.WriteAllBytes(output, uncompressed); }
private void ImportDlcVillager() { if (_villager.Data.VillagerId < 0xE0EC || _villager.Data.VillagerId > 0xE0FF) { MessageBox.Show("You must set your villager to one of the DLC villagers before importing!", "DLC Villager Import Info"); return; } using (var openFileDialog = new OpenFileDialog { Filter = "Yaz0 compressed file|*.yaz0" }) { if (openFileDialog.ShowDialog() != DialogResult.OK) { return; } byte[] villagerData = null; try { villagerData = System.IO.File.ReadAllBytes(openFileDialog.FileName); } catch { MessageBox.Show("An error occurred while importing the DLC villager info.\nPlease try again!", "DLC Villager Import Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { if (villagerData != null) { _villager.ImportDlcVillager(villagerData, (_villager.Data.VillagerId - 0xEC) & 0xFF); // Decompress Yaz0 data and set accordingly var decompressedData = Yaz0.Decompress(villagerData); _villager.Name = new AcString(decompressedData.Skip(1).Take(6).ToArray(), _saveFile.SaveType).Trim(); _villager.Data.Catchphrase = new AcString(decompressedData.Skip(7).Take(4).ToArray(), _saveFile.SaveType).Trim(); _shirtEditor.Item = new Item((ushort)(0x2400 | decompressedData[0xE])); _villager.Data.Personality = decompressedData[0xD]; // Update controls to reflect changes _nameBox.Text = _villager.Name; _catchphraseBox.Text = _villager.Data.Catchphrase; _personalityBox.SelectedIndex = _villager.Data.Personality; MessageBox.Show("DLC Villager import was succsessful!", "DLC Villager Import Info", MessageBoxButtons.OK, MessageBoxIcon.Information); } } } }
/// <summary> /// Creates an archive out of the specified <see cref="VirtualFilesystemDirectory"/>, optionally compressing the resulting file. /// </summary> /// <param name="outputPath">Filepath to which to write the file to.</param> /// <param name="root"><see cref="VirtualFilesystemDirectory"/> to create an archive out of.</param> /// <param name="compression">Optionally compress with Yaz0 or Yay0 compression.</param> public static void WriteArchive(string outputPath, VirtualFilesystemDirectory root, ArchiveCompression compression = ArchiveCompression.Uncompressed) { if (string.IsNullOrEmpty(outputPath)) { throw new ArgumentNullException("filePath", "Cannot write archive to empty file path!"); } if (root == null) { throw new ArgumentNullException("root", "Cannot write null VirtualFilesystemDirectory to archive."); } Archive rarc = new Archive(); MemoryStream outputData = new MemoryStream(); // Create an archive structure from the given root and write it to file. Compression will be applied if specified. MemoryStream uncompressedStream = new MemoryStream(); using (EndianBinaryWriter fileWriter = new EndianBinaryWriter(uncompressedStream, Endian.Big)) { byte[] rawData = rarc.WriteFile(root); fileWriter.Write(rawData); fileWriter.Seek(0, SeekOrigin.Begin); fileWriter.BaseStream.CopyTo(outputData); } MemoryStream compressedStream = new MemoryStream(); switch (compression) { case ArchiveCompression.Yay0: throw new NotImplementedException("Yay0 Compression not implemented."); //compressedStream = Yay0.Encode(uncompressedStream); //break; case ArchiveCompression.Yaz0: EndianBinaryWriter encoded = Yaz0.Encode(uncompressedStream); encoded.Seek(0, SeekOrigin.Begin); encoded.BaseStream.CopyTo(compressedStream); break; case ArchiveCompression.Uncompressed: // Well, that was easy. compressedStream = uncompressedStream; break; } compressedStream.Seek(0, SeekOrigin.Begin); compressedStream.WriteTo(File.Create(outputPath)); }
private void UpdateModel() { // Loads the necessary information about which figurine model to load dynamically from the REL and the DOL. m_actorMeshes = WResourceManager.LoadActorResource("Figurine Stand"); int modelFileID; int modelArcIndex; int figurineIndex = (int)WhichFigurine; string figurine_rel_path = Path.Combine(WSettingsManager.GetSettings().RootDirectoryPath, "files", "rels/d_a_obj_figure.rel"); MemoryStream figurine_rel_data = null; using (EndianBinaryReader reader = new EndianBinaryReader(File.ReadAllBytes(figurine_rel_path), Endian.Big)) { figurine_rel_data = Yaz0.Decode(reader); } using (EndianBinaryReader reader = new EndianBinaryReader(figurine_rel_data, Endian.Big)) { int l_figure_dat_entry_offset = l_figure_dat_tbl_offset + figurineIndex * 0xC; modelFileID = reader.ReadInt32At(l_figure_dat_entry_offset + 0x00); modelArcIndex = reader.ReadInt32At(l_figure_dat_entry_offset + 0x08); } if (modelArcIndex == -1) { string main_dol_path = Path.Combine(WSettingsManager.GetSettings().RootDirectoryPath, "sys", "main.dol"); using (FileStream strm = new FileStream(main_dol_path, FileMode.Open, FileAccess.Read)) { EndianBinaryReader reader = new EndianBinaryReader(strm, Endian.Big); long l_CharaData_entry_address = l_CharaData_address + figurineIndex * 0x12; long l_CharaData_entry_offset = DOL.AddressToOffset(l_CharaData_entry_address, reader); modelArcIndex = reader.ReadByteAt(l_CharaData_entry_offset + 0x10); } } var arc_name = l_arcname_tbl[modelArcIndex]; string arc_path = Path.Combine(WSettingsManager.GetSettings().RootDirectoryPath, "files", "res/Object/", arc_name + ".arc"); if (File.Exists(arc_path)) { VirtualFilesystemDirectory model_arc = ArchiveUtilities.LoadArchive(arc_path); if (model_arc.FindByID((ushort)modelFileID) != null) { var figurine_model = WResourceManager.LoadModelFromVFS(model_arc, fileID: (ushort)modelFileID); figurine_model.SetOffsetTranslation(new Vector3(0, 100, 0)); m_actorMeshes.Add(figurine_model); } } }
private static Stream CompressFileFormat(ICompressionFormat compressionFormat, Stream data, bool FileIsCompressed, int Alignment, string FileName, bool EnableDialog = true) { string extension = Path.GetExtension(FileName); if (extension == ".szs" || extension == ".sbfres") { FileIsCompressed = true; compressionFormat = new Yaz0(); } if (compressionFormat == null) { return(data); } bool CompressFile = false; if (EnableDialog && FileIsCompressed) { if (Runtime.AlwaysCompressOnSave) { CompressFile = true; } else { DialogResult save = MessageBox.Show($"Compress file with {compressionFormat}?", "File Save", MessageBoxButtons.YesNo); CompressFile = (save == DialogResult.Yes); } } else if (FileIsCompressed) { CompressFile = true; } Console.WriteLine($"FileIsCompressed {FileIsCompressed} CompressFile {CompressFile} CompressionType {compressionFormat}"); if (CompressFile) { if (compressionFormat is Yaz0) { ((Yaz0)compressionFormat).Alignment = Alignment; } return(compressionFormat.Compress(data)); } return(data); }
/// <summary> /// Loads an archive into a <see cref="VirtualFilesystemDirectory"/>, automatically de-compressing the archive if required. /// </summary> /// <param name="filePath">Filepath of file to decompress and load.</param> /// <returns><see cref="VirtualFilesystemDirectory"/> containing the contents, or null if not an archive.</returns> public static VirtualFilesystemDirectory LoadArchive(string filePath) { if (string.IsNullOrEmpty(filePath)) { throw new ArgumentNullException("filePath", "Cannot load archive from empty file path!"); } if (!File.Exists(filePath)) { throw new ArgumentException("Cannot load archive from non-existant file!", "filePath"); } MemoryStream decompressedFile = null; using (EndianBinaryReader fileReader = new EndianBinaryReader(File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Endian.Big)) { // Read the first 4 bytes to see if it's a compressed file (Yaz0) or a plain RARC file. uint fileMagic = fileReader.ReadUInt32(); fileReader.BaseStream.Position = 0L; // Reset to the start so that the next thing to read it is at the start like it expects. if (fileMagic == 0x59617A30) // Yaz0 { Yaz0 yaz0 = new Yaz0(); decompressedFile = yaz0.Decode(fileReader); } else if (fileMagic == 0x52415243) // RARC { // Copy the fileReader stream to a new memorystream. decompressedFile = new MemoryStream((int)fileReader.BaseStream.Length); fileReader.BaseStream.CopyTo(decompressedFile); decompressedFile.Position = 0L; } } // Not an archive we know how to handle. if (decompressedFile == null) { return(null); } // Decompress the archive into the folder. It'll generate a sub-folder with the Archive's ROOT name. RARC rarc = new RARC(); using (EndianBinaryReader reader = new EndianBinaryReader(decompressedFile, Endian.Big)) { return(rarc.ReadFile(reader)); } }
/// <summary> /// Loads a file into a <see cref="EndianBinaryReader"/>, automatically de-compressing the file if required. /// Throws an exception if the filepath to the file is not valid. /// </summary> /// <param name="filePath">Filepath of file to (optionally) decompress and load.</param> /// <returns><see cref="EndianBinaryReader"/> containing the contents.</returns> public static EndianBinaryReader LoadFile(string filePath) { if (string.IsNullOrEmpty(filePath)) { throw new ArgumentNullException("filePath", "Cannot load archive from empty file path!"); } if (!File.Exists(filePath)) { throw new ArgumentException("Cannot load archive from non-existant file!", "filePath"); } MemoryStream decompressedFile = null; using (EndianBinaryReader fileReader = new EndianBinaryReader(File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Endian.Big)) { // Read the first 4 bytes to see if it's a compressed file (Yaz0, Yay0, etc.) uint fileMagic = fileReader.ReadUInt32(); fileReader.BaseStream.Position = 0L; // Reset to the start so that the next thing to read it is at the start like it expects. switch (fileMagic) { case 0x59617A30: // Yaz0 Compression decompressedFile = Yaz0.Decode(fileReader); break; case 0x59617930: // Yay0 Compression decompressedFile = Yay0.Decode(fileReader); break; default: // Uncompressed decompressedFile = new MemoryStream((int)fileReader.BaseStream.Length); fileReader.BaseStream.CopyTo(decompressedFile); // CopyTo modifies the decompressedFile's read head (places it at new location) so we rewind. decompressedFile.Position = 0L; break; } } // Return the decompressed file return(new EndianBinaryReader(decompressedFile, Endian.Big)); }
private void Yaz0CompressLittleEndianToolStripMenuItem_Click(object sender, EventArgs e) { if (openxmlFileDialog.ShowDialog() == DialogResult.OK) { FileInfo file = new FileInfo(openyamlFileDialog.FileName); saveyaz0FileDialog.ShowDialog(); if (saveyaz0FileDialog.FileName != "") { FileInfo selected = new FileInfo(saveFileDialog.FileName); //TODO: Change to using. FileStream byml = file.OpenRead(); File.WriteAllBytes(selected.FullName, Yaz0.Encode(byml)); byml.Close(); saveyaz0FileDialog.FileName = ""; } } }
private void decompressYaz0ToolStripMenuItem_Click(object sender, EventArgs e) { try { using (var ofd = new OpenFileDialog()) { if (ofd.ShowDialog(this) != DialogResult.OK) { return; } using (var stream = ofd.OpenFile()) using (var outputStream = new MemoryStream()) { Yaz0.Decompress(stream, outputStream); using (var sfd = new SaveFileDialog()) { sfd.FileName = ofd.FileName; if (sfd.ShowDialog(this) != DialogResult.OK) { return; } using (var outputFile = sfd.OpenFile()) { outputStream.Seek(0, SeekOrigin.Begin); outputStream.CopyTo(outputFile); } } } } } catch (Exception ex) { MessageBox.Show(ex.Message); } }
static void Test(byte[] bytes, Method method) { var bytes2 = new byte[bytes.Length]; switch (method) { case Method.RLE: bytes2 = RLE.Decompress(new MemoryStream(RLE.Compress(new MemoryStream(bytes))), bytes.Length); Assert.IsTrue(bytes.SequenceEqual(bytes2)); break; case Method.Yaz0: bytes2 = Yaz0.Decompress(new MemoryStream(Yaz0.Compress(new MemoryStream(bytes)))); Assert.IsTrue(bytes.SequenceEqual(bytes2)); break; case Method.Yay0: bytes2 = Yay0.Decompress(new MemoryStream(Yay0.Compress(new MemoryStream(bytes)))); Assert.IsTrue(bytes.SequenceEqual(bytes2)); break; } }
/// <summary> /// Creates an new file out of the specified <see cref="EndianBinaryWriter"/>, optionally compressing the resulting file. /// </summary> /// <param name="outputPath">Filepath to which to write the file to.</param> /// <param name="stream"><see cref="MemoryStream"/> to create an archive out of.</param> /// <param name="compression">Optionally compress with Yaz0 or Yay0 compression.</param> public static void SaveFile(string outputPath, MemoryStream stream, ArchiveCompression compression = ArchiveCompression.Uncompressed) { if (string.IsNullOrEmpty(outputPath)) { throw new ArgumentNullException("filePath", "Cannot write archive to empty file path!"); } if (stream == null) { throw new ArgumentNullException("root", "Cannot write null EndianBinaryWriter to archive."); } MemoryStream compressedStream = new MemoryStream(); switch (compression) { case ArchiveCompression.Yay0: throw new NotImplementedException("Yay0 Compression not implemented."); //compressedStream = Yay0.Encode(uncompressedStream); //break; case ArchiveCompression.Yaz0: EndianBinaryWriter encoded = Yaz0.Encode(stream); encoded.Seek(0, SeekOrigin.Begin); encoded.BaseStream.CopyTo(compressedStream); break; case ArchiveCompression.Uncompressed: // Well, that was easy. compressedStream = stream; break; } compressedStream.Seek(0, SeekOrigin.Begin); using (var fileStream = File.Create(outputPath)) compressedStream.WriteTo(fileStream); }
public void Save(string filename = "") { if (!string.IsNullOrEmpty(filename)) { FileInfo = new FileInfo(filename); } // Save As... if (!string.IsNullOrEmpty(filename)) { var ms = new MemoryStream(); _sarc.Save(ms, true); _sarc.Close(); using (var bw = new BinaryWriterX(FileInfo.Create())) { bw.Write(Yaz0.Compress(ms, ByteOrder.BigEndian)); } } else { // Create the temp file var ms = new MemoryStream(); _sarc.Save(ms, true); _sarc.Close(); using (var bw = new BinaryWriterX(File.Create(FileInfo.FullName + ".tmp"))) { bw.Write(Yaz0.Compress(ms, ByteOrder.BigEndian)); } // Delete the original FileInfo.Delete(); // Rename the temporary file File.Move(FileInfo.FullName + ".tmp", FileInfo.FullName); } // Reload the new file to make sure everything is in order Load(FileInfo.FullName); }
public static void Compress(object sender, EventArgs e) { var tsi = sender as ToolStripMenuItem; if (!Shared.PrepareFiles("Open a decompressed " + tsi?.Tag + "file...", "Save your compressed file...", ".decomp", out var openFile, out var saveFile, true)) { return; } try { using (openFile) using (var outFs = new BinaryWriterX(saveFile)) switch (tsi?.Tag) { case Compression.L5LZ10: outFs.Write(Level5.Compress(openFile, Level5.Method.LZ10)); break; case Compression.L5Huff4: outFs.Write(Level5.Compress(openFile, Level5.Method.Huffman4Bit)); break; case Compression.L5Huff8: outFs.Write(Level5.Compress(openFile, Level5.Method.Huffman8Bit)); break; case Compression.L5RLE: outFs.Write(Level5.Compress(openFile, Level5.Method.RLE)); break; case Compression.NLZ10: outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.LZ10)); break; case Compression.NLZ11: outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.LZ11)); break; case Compression.NLZ60: outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.LZ60)); break; case Compression.NHuff4: outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.Huff4)); break; case Compression.NHuff8: outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.Huff8)); break; case Compression.NRLE: outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.RLE)); break; case Compression.LZ77: outFs.Write(LZ77.Compress(openFile)); break; case Compression.RevLZ77: outFs.Write(RevLZ77.Compress(openFile)); break; case Compression.LZOvl: outFs.Write(LZOvl.Compress(openFile)); break; case Compression.LZ4: outFs.Write(Kontract.Compression.LZ4.Compress(openFile)); break; case Compression.MIO0LE: outFs.Write(MIO0.Compress(openFile, ByteOrder.LittleEndian)); break; case Compression.MIO0BE: outFs.Write(MIO0.Compress(openFile, ByteOrder.BigEndian)); break; case Compression.Yay0LE: outFs.Write(Yay0.Compress(openFile, ByteOrder.LittleEndian)); break; case Compression.Yay0BE: outFs.Write(Yay0.Compress(openFile, ByteOrder.BigEndian)); break; case Compression.Yaz0LE: outFs.Write(Yaz0.Compress(openFile, ByteOrder.LittleEndian)); break; case Compression.Yaz0BE: outFs.Write(Yaz0.Compress(openFile, ByteOrder.BigEndian)); break; case Compression.GZip: outFs.Write(GZip.Compress(openFile)); break; case Compression.ZLib: outFs.Write(ZLib.Compress(openFile)); break; case Compression.PSVSpikeChun: outFs.Write(PSVSpikeChun.Compress(openFile)); break; } } catch (Exception ex) { MessageBox.Show(ex.ToString(), tsi?.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } MessageBox.Show($"Successfully compressed {Path.GetFileName(openFile.Name)}.", tsi.Text, MessageBoxButtons.OK, MessageBoxIcon.Information); }
public static void Decompress(object sender, EventArgs e) { var tsi = sender as ToolStripMenuItem; if (!Shared.PrepareFiles("Open a " + tsi?.Tag + " compressed file...", "Save your decompressed file...", ".decomp", out var openFile, out var saveFile)) { return; } try { using (openFile) using (var outFs = new BinaryWriterX(saveFile)) switch (tsi?.Tag) { case Compression.Level5: outFs.Write(Level5.Decompress(openFile)); break; case Compression.Nintendo: outFs.Write(Nintendo.Decompress(openFile)); break; case Compression.LZ77: outFs.Write(LZ77.Decompress(openFile)); break; case Compression.RevLZ77: outFs.Write(RevLZ77.Decompress(openFile)); break; case Compression.LZOvl: outFs.Write(LZOvl.Decompress(openFile)); break; case Compression.LZ4: outFs.Write(Kontract.Compression.LZ4.Decompress(openFile)); break; case Compression.MIO0LE: outFs.Write(MIO0.Decompress(openFile, ByteOrder.LittleEndian)); break; case Compression.MIO0BE: outFs.Write(MIO0.Decompress(openFile, ByteOrder.BigEndian)); break; case Compression.Yay0LE: outFs.Write(Yay0.Decompress(openFile, ByteOrder.LittleEndian)); break; case Compression.Yay0BE: outFs.Write(Yay0.Decompress(openFile, ByteOrder.BigEndian)); break; case Compression.Yaz0LE: outFs.Write(Yaz0.Decompress(openFile, ByteOrder.LittleEndian)); break; case Compression.Yaz0BE: outFs.Write(Yaz0.Decompress(openFile, ByteOrder.BigEndian)); break; case Compression.LZECD: outFs.Write(LZECD.Decompress(openFile)); break; case Compression.LZ10VLE: outFs.Write(LZSSVLE.Decompress(openFile)); break; case Compression.GZip: outFs.Write(GZip.Decompress(openFile)); break; case Compression.ZLib: outFs.Write(ZLib.Decompress(openFile)); break; case Compression.PSVSpikeChun: outFs.Write(PSVSpikeChun.Decompress(openFile)); break; } } catch (Exception ex) { MessageBox.Show(ex.ToString(), tsi?.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } MessageBox.Show($"Successfully decompressed {Path.GetFileName(openFile.Name)}.", tsi.Text, MessageBoxButtons.OK, MessageBoxIcon.Information); }
/// <summary> /// Process data in an input file that contains a layout. /// </summary> /// <param name="filename"></param> bool ProcessData(string filename, byte[] inData) { EndianBinaryReader reader = null; // now we need to decide what they just opened if (inData == null && filename != "") { reader = new EndianBinaryReader(File.Open(filename, FileMode.Open), Encoding.GetEncoding(932)); } else { reader = new EndianBinaryReader(inData); } string magic = ""; // we have a Yaz0 compressed file if (reader.ReadStringFrom(0, 4) == "Yaz0") { // we have to close our reader so we can properly read this file as a Yaz0 stream reader.Close(); MemoryStream ms = null; if (inData == null) { ms = new Yaz0(File.Open(filename, FileMode.Open)); } else { ms = new Yaz0(new MemoryStream(inData)); } reader = new EndianBinaryReader(ms); magic = reader.ReadStringFrom(0, 4); } // we have a LZ compressed file else if (reader.ReadByteFrom(0) == 0x11) { LZ77 lzFile = new LZ77(ref reader); byte[] lzData = lzFile.getData(); // close our current reader to open a new one with our input data reader.Close(); reader = new EndianBinaryReader(lzData); magic = reader.ReadStringFrom(0, 4); } // no compression else { // it is not yaz0 compressed, so we see the magic magic = reader.ReadStringFrom(0, 4); } // now we have to check our magic to see what kind of file it is switch (magic) { case "darc": mArchive = new DARC(ref reader); break; case "NARC": mArchive = new NARC(ref reader); break; case "SARC": mArchive = new SARC(ref reader); break; case "RARC": reader.SetEndianess(Endianess.Big); mArchive = new RARC(ref reader); break; case "U?8-": reader.SetEndianess(Endianess.Big); mArchive = new U8(ref reader); break; default: MessageBox.Show("Error. Unsupported format with magic: " + magic); break; } string layoutType = ""; // some files have their string table nullified, which makes the names obfuscated // I've only seen this in SARCs from MK7, but there's probably more if (mArchive != null) { if (mArchive.isStringTableObfuscated()) { MessageBox.Show("This file has obfuscated file names. The editor attempted to find layout files, but cannot supply names."); } } reader.Close(); if (mArchive == null) { MessageBox.Show("Format not supported."); return(false); } // the only familiar format with archives in archives is SARC and RARC if (mArchive.getType() == ArchiveType.SARC || mArchive.getType() == ArchiveType.RARC) { List <string> names = mArchive.getArchiveFileNames(); if (names.Count != 0) { DialogResult res = MessageBox.Show("This archive has another archive inside of it.\nDo you wish to choose one of the found archives to select a layout?", "Internal Archive", MessageBoxButtons.YesNo); if (res == DialogResult.Yes) { LayoutChooser archiveChooser = new LayoutChooser(); archiveChooser.insertEntries(names); archiveChooser.ShowDialog(); // if this worked, we dont need to do anything bool result = ProcessData(archiveChooser.getSelectedFile(), mArchive.getDataByName(archiveChooser.getSelectedFile())); if (result) { return(true); } else { MessageBox.Show("Failed to get the internal file."); return(false); } } } } // get all of our needed files mLayoutFiles = mArchive.getLayoutFiles(); mLayoutAnimFiles = mArchive.getLayoutAnimations(); mLayoutImages = mArchive.getLayoutImages(); mLayoutControls = mArchive.getLayoutControls(); if (mLayoutFiles.Count == 0) { MessageBox.Show("This file contains no layouts."); return(false); } LayoutChooser layoutChooser = new LayoutChooser(); layoutChooser.insertEntries(new List <string>(mLayoutFiles.Keys)); layoutChooser.ShowDialog(); string selectedFile = layoutChooser.getSelectedFile(); if (selectedFile == null) { return(false); } string[] sections = selectedFile.Split('/'); mMainRoot = ""; // remove "lyt" part and the file name // this will be our main root of the entire opened file for (int i = 0; i < sections.Length - 2; i++) { mMainRoot += sections[i] + "/"; } if (layoutType == "") { layoutType = Path.GetExtension(selectedFile); } // now we have to init a layout reader EndianBinaryReader layoutReader = null; byte[] data; switch (layoutType) { case ".brlyt": data = mLayoutFiles[selectedFile]; layoutReader = new EndianBinaryReader(data); mMainLayout = new BRLYT(ref layoutReader); layoutReader.Close(); break; case ".bclyt": data = mLayoutFiles[selectedFile]; layoutReader = new EndianBinaryReader(data); mMainLayout = new BCLYT(ref layoutReader); break; case ".bflyt": data = mLayoutFiles[selectedFile]; layoutReader = new EndianBinaryReader(data); mMainLayout = new BFLYT(ref layoutReader); break; case ".blo": data = mLayoutFiles[selectedFile]; layoutReader = new EndianBinaryReader(data); if (layoutReader.ReadStringFrom(4, 4) == "blo1") { mMainLayout = new BLO1(ref layoutReader); } else { mMainLayout = new BLO2(ref layoutReader); } break; default: MessageBox.Show("This format is not supported yet."); break; } layoutReader.Close(); if (mMainLayout == null) { return(false); } // set our propertygrid with our LYT object mainPropertyGrid.SelectedObject = mMainLayout.getLayoutParams(); if (mMainLayout.getRootPanel() == null) { MessageBox.Show("Error, the root pane in this layout is not specified."); return(false); } LayoutBase pane = null; LayoutBase group = null; // now we have to grab our root panel, which is different on each console // so we have to specifically get the one we want // the same applies to our root group pane = mMainLayout.getRootPanel(); // this should be RootPane TreeNode n1 = new TreeNode { Tag = pane, Name = pane.mName, Text = pane.mName, }; panelList.Nodes.Add(n1); fillNodes(pane.getChildren()); // now for our groups group = mMainLayout.getRootGroup(); if (group != null) { TreeNode n1_1 = new TreeNode { Tag = group, Name = group.mName, Text = group.mName, }; panelList.Nodes.Add(n1_1); fillNodes(group.getChildren()); } // now for textures and fonts // but it is possible for either one to not exist if (mMainLayout.containsTextures()) { foreach (string str in mMainLayout.getTextureNames()) { texturesList.Items.Add(str); } } if (mMainLayout.containsFonts()) { foreach (string str in mMainLayout.getFontNames()) { fontsList.Items.Add(str); } } // and our materials if (mMainLayout.containsMaterials()) { foreach (string str in mMainLayout.getMaterialNames()) { materialList.Items.Add(str); } } // this draws the border of the layout mMainLayout.draw(); layoutViewer.Refresh(); return(true); }
public static file load(Stream data) { //Too small if (data.Length < 0x10) { data.Close(); return(new file { type = formatType.unsupported }); } BinaryReader input = new BinaryReader(data); uint magic, length; switch (peek(input)) { case 0x00010000: return(new file { data = GfModel.load(data), type = formatType.model }); case 0x00060000: return(new file { data = GfMotion.loadAnim(input), type = formatType.anims }); case 0x15041213: return(new file { data = GfTexture.load(data), type = formatType.image }); case 0x15122117: RenderBase.OModelGroup mdls = new RenderBase.OModelGroup(); mdls.model.Add(GfModel.loadModel(data)); return(new file { data = mdls, type = formatType.model }); } switch (getMagic(input, 5)) { case "MODEL": return(new file { data = DQVIIPack.load(data), type = formatType.container }); } switch (getMagic(input, 4)) { case "CGFX": return(new file { data = CGFX.load(data), type = formatType.model }); case "CRAG": return(new file { data = GARC.load(data), type = formatType.container }); case "darc": return(new file { data = DARC.load(data), type = formatType.container }); case "FPT0": return(new file { data = FPT0.load(data), type = formatType.container }); case "IECP": magic = input.ReadUInt32(); length = input.ReadUInt32(); return(load(new MemoryStream(LZSS.decompress(data, length)))); case "NLK2": data.Seek(0x80, SeekOrigin.Begin); return(new file { data = CGFX.load(data), type = formatType.model }); case "SARC": return(new file { data = SARC.load(data), type = formatType.container }); case "SMES": return(new file { data = NLP.loadMesh(data), type = formatType.model }); case "Yaz0": magic = input.ReadUInt32(); length = IOUtils.endianSwap(input.ReadUInt32()); data.Seek(8, SeekOrigin.Current); return(load(new MemoryStream(Yaz0.decompress(data, length)))); case "zmdl": return(new file { data = ZMDL.load(data), type = formatType.model }); case "ztex": return(new file { data = ZTEX.load(data), type = formatType.texture }); } //Check if is a BCLIM or BFLIM file (header on the end) if (data.Length > 0x28) { data.Seek(-0x28, SeekOrigin.End); string clim = IOUtils.readStringWithLength(input, 4); if (clim == "CLIM" || clim == "FLIM") { return new file { data = BCLIM.load(data), type = formatType.image } } ; } switch (getMagic(input, 3)) { case "BCH": byte[] buffer = new byte[data.Length]; input.Read(buffer, 0, buffer.Length); data.Close(); return(new file { data = BCH.load(new MemoryStream(buffer)), type = formatType.model }); case "DMP": return(new file { data = DMP.load(data), type = formatType.image }); } string magic2b = getMagic(input, 2); switch (magic2b) { case "AD": return(new file { data = AD.load(data), type = formatType.model }); case "BM": return(new file { data = MM.load(data), type = formatType.model }); case "BS": return(new file { data = BS.load(data), type = formatType.anims }); case "CM": return(new file { data = CM.load(data), type = formatType.model }); case "CP": return(new file { data = CP.load(data), type = formatType.model }); case "GR": return(new file { data = GR.load(data), type = formatType.model }); case "MM": return(new file { data = MM.load(data), type = formatType.model }); case "PC": return(new file { data = PC.load(data), type = formatType.model }); case "PT": return(new file { data = PT.load(data), type = formatType.texture }); } if (magic2b.Length == 2) { if ((magic2b[0] >= 'A' && magic2b[0] <= 'Z') && (magic2b[1] >= 'A' && magic2b[1] <= 'Z')) { return(new file { data = PkmnContainer.load(data), type = formatType.container }); } } //Compressions data.Seek(0, SeekOrigin.Begin); uint cmp = input.ReadUInt32(); if ((cmp & 0xff) == 0x13) { cmp = input.ReadUInt32(); } switch (cmp & 0xff) { case 0x11: return(load(new MemoryStream(LZSS_Ninty.decompress(data, cmp >> 8)))); case 0x90: byte[] buffer = BLZ.decompress(data); byte[] newData = new byte[buffer.Length - 1]; Buffer.BlockCopy(buffer, 1, newData, 0, newData.Length); return(load(new MemoryStream(newData))); } data.Close(); return(new file { type = formatType.unsupported }); }
private static void ExtractArchive(string outputFolder, string filePath) { if (!File.Exists(filePath)) { Console.WriteLine("Warning: Tried to extract archive from filePath \"{0}\" but not a file!", filePath); return; } if (m_verboseOutput) { Console.Write("Extracting archive {0}... ", Path.GetFileName(filePath)); } try { MemoryStream decompressedFile = null; using (EndianBinaryReader fileReader = new EndianBinaryReader(File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Endian.Big)) { // Read the first 4 bytes to see if it's a compressed file (Yaz0) or a plain RARC file. uint fileMagic = fileReader.ReadUInt32(); fileReader.BaseStream.Position = 0L; // Reset to the start so that the next thing to read it is at the start like it expects. if (fileMagic == 0x59617A30) // Yaz0 { if (m_verboseOutput) { Console.Write("Archive compressed with Yaz0, decompressing... "); } decompressedFile = Yaz0.Decode(fileReader); } if (fileMagic == 0x59617930) // Yay0 { if (m_verboseOutput) { Console.Write("Archive compressed with Yay0, decompressing... "); } decompressedFile = Yay0.Decode(fileReader); } else if (fileMagic == 0x52415243) // RARC { // Copy the fileReader stream to a new memorystream. decompressedFile = new MemoryStream((int)fileReader.BaseStream.Length); fileReader.BaseStream.CopyTo(decompressedFile); decompressedFile.Position = 0L; } } if (decompressedFile == null) { if (m_verboseOutput) { Console.WriteLine("Skipping archive, not a Yaz0 or RARC file."); } return; } // Decompress the archive into the folder. It'll generate a sub-folder with the Archive's ROOT name. Archive rarc = new Archive(); using (EndianBinaryReader reader = new EndianBinaryReader(decompressedFile, Endian.Big)) { VirtualFilesystemDirectory root = rarc.ReadFile(reader); if (m_printFS) { PrintFileSystem(root); } // Many archives use the same internal root name, which causes a conflict when they export. // To solve this, we use the file name of the file as the root name, instead of the internal // name. if (!m_useInternalNames) { root.Name = Path.GetFileNameWithoutExtension(filePath); } // Write it to disk. root.ExportToDisk(outputFolder); } if (m_verboseOutput) { Console.WriteLine("Completed."); } } catch (Exception ex) { Console.WriteLine("Caught Exception: " + ex.ToString()); m_wasError = true; } }
public void InjectFile(int vrom, byte[] data) { var file = GetFile(vrom); if (file == null) { throw new Z64GameException("Invalid VROM"); } int oldSize = file.Compressed ? file.RomEnd - file.RomStart : file.Data.Length; var restStart = file.RomEnd != 0 ? file.RomEnd : file.RomStart + file.Data.Length; //find rom end Z64File last = null; for (int i = 0; i < GetFileCount(); i++) { var iter = GetFileFromIndex(i); if (iter.Valid() && !iter.Deleted && (last == null || iter.RomStart > last.RomStart)) { last = iter; } } if (last == null) { throw new Exception("?"); } var restEnd = last.RomEnd; //save rest byte[] rest = new byte[restEnd - restStart]; Buffer.BlockCopy(Rom.RawRom, restStart, rest, 0, rest.Length); var encData = file.Compressed ? Yaz0.Compress(data) : data; int off = encData.Length - oldSize; //copy new file in rom Buffer.BlockCopy(encData, 0, Rom.RawRom, file.RomStart, encData.Length); file.Data = data; file.VRomEnd = (file.VRomStart + data.Length) + 0xF & ~0xF; if (file.Compressed) { file.RomEnd = (file.RomStart + encData.Length) + 0xF & ~0xF; } //copy rest Buffer.BlockCopy(rest, 0, Rom.RawRom, file.RomEnd, rest.Length); //offset each file rom addresses for (int i = _files.IndexOf(file) + 1; i < _files.Count; i++) { _files[i].RomStart = (_files[i].RomStart + off) + 0xF & ~0xF; _files[i].RomEnd = (_files[i].RomEnd + off) + 0xF & ~0xF; } file.Data = data; file.Deleted = false; }
private static J3D LoadModelFromResource(WActorResource.ModelResource res, string archive) { J3D j3d = null; if (string.IsNullOrEmpty(res.Path) || string.IsNullOrEmpty(archive)) { return(null); } string archivePath = Path.Combine(WSettingsManager.GetSettings().RootDirectoryPath, "files", "res/Object/", archive + ".arc"); if (!File.Exists(archivePath)) { return(null); } VirtualFilesystemDirectory model_arc = ArchiveUtilities.LoadArchive(archivePath); VirtualFilesystemFile archiveFile = model_arc.GetFileAtPath(res.Path); if (archiveFile == null) { Console.WriteLine("LoadActorByName failed because the specified path \"{0}\" does not exist in archive \"{1}\"!", res.Path, archive); return(null); } byte[] j3dData = archiveFile.Data; j3d = new J3D(archiveFile.Name); using (EndianBinaryReader reader = new EndianBinaryReader(j3dData, Endian.Big)) j3d.LoadFromStream(reader, WSettingsManager.GetSettings().DumpTextures, WSettingsManager.GetSettings().DumpShaders); if (res.Position != null) { j3d.SetOffsetTranslation((Vector3)res.Position); } if (res.Rotation != null) { j3d.SetOffsetRotation((Vector3)res.Rotation); } if (res.Scale != null) { j3d.SetOffsetScale((Vector3)res.Scale); } j3d.SetHardwareLight(0, m_mainLight); j3d.SetHardwareLight(1, m_secondaryLight); j3d.SetTextureOverride("ZBtoonEX", "resources/textures/ZBtoonEX.png"); j3d.SetTextureOverride("ZAtoon", "resources/textures/ZAtoon.png"); if (res.Animations == null) { res.Animations = new WActorResource.AnimationResource[0]; } foreach (var anim in res.Animations) { VirtualFilesystemDirectory anim_arc = model_arc; if (!string.IsNullOrEmpty(anim.ArchiveName)) { string anim_arc_path = Path.Combine(WSettingsManager.GetSettings().RootDirectoryPath, "files", "res/Object/", anim.ArchiveName + ".arc"); if (!File.Exists(anim_arc_path)) { return(null); } anim_arc = ArchiveUtilities.LoadArchive(anim_arc_path); } VirtualFilesystemFile anim_file = anim_arc.GetFileAtPath(anim.Path); if (anim_file == null) { continue; } byte[] anim_data = anim_file.Data; // Decompress the file if necessary if (anim_data[0] == 'Y') { MemoryStream decompressed_data = null; using (EndianBinaryReader decompressor = new EndianBinaryReader(anim_data, Endian.Big)) { decompressed_data = Yaz0.Decode(decompressor); } anim_data = decompressed_data.ToArray(); } switch (anim.Type) { case "bck": BCK loaded_bck = new BCK(anim_file.Name); using (EndianBinaryReader reader = new EndianBinaryReader(anim_data, Endian.Big)) loaded_bck.LoadFromStream(reader); j3d.BoneAnimations.Add(loaded_bck); j3d.SetBoneAnimation(anim_file.Name); loaded_bck.Tick(anim.StartTime); if (anim.PausedOnLoad) { loaded_bck.Pause(); } break; case "btk": BTK loaded_btk = new BTK(anim_file.Name); using (EndianBinaryReader reader = new EndianBinaryReader(anim_data, Endian.Big)) loaded_btk.LoadFromStream(reader); j3d.MaterialAnimations.Add(loaded_btk); j3d.SetMaterialAnimation(anim_file.Name); loaded_btk.Tick(anim.StartTime); if (anim.PausedOnLoad) { loaded_btk.Pause(); } break; case "brk": BRK loaded_brk = new BRK(anim_file.Name); using (EndianBinaryReader reader = new EndianBinaryReader(anim_data, Endian.Big)) loaded_brk.LoadFromStream(reader); j3d.RegisterAnimations.Add(loaded_brk); j3d.SetRegisterAnimation(anim_file.Name); loaded_brk.Tick(anim.StartTime); if (anim.PausedOnLoad) { loaded_brk.Pause(); } break; case "bmt": BMT loaded_bmt = new BMT(anim_file.Name); using (EndianBinaryReader reader = new EndianBinaryReader(anim_data, Endian.Big)) loaded_bmt.LoadFromStream(reader); j3d.ExternalMaterials.Add(loaded_bmt); j3d.SetExternalMaterial(anim_file.Name); if (loaded_bmt.MAT3 != null) { // a hack to get bmts working Material dummyMat = null; j3d.AssignVertexAttributesToMaterialsRecursive(j3d.INF1Tag.HierarchyRoot, ref dummyMat, loaded_bmt.MAT3); j3d.GenerateShadersForMaterials(loaded_bmt.MAT3); } break; default: break; } } j3d.Tick(1 / (float)60); if (res.ChildModels == null) { res.ChildModels = new WActorResource.ModelResource[0]; } foreach (var childRes in res.ChildModels) { var childJ3d = LoadModelFromResource(childRes, archive); j3d.AddChildModel(childJ3d, childRes.ParentJointName); } return(j3d); }