public NitroOverlay(NitroROM rom, uint id) { m_ROM = rom; m_ID = id; bool autorw = !m_ROM.CanRW(); if (autorw) { m_ROM.BeginRW(); } m_OVTEntryAddr = m_ROM.GetOverlayEntryOffset(m_ID); m_FileID = m_ROM.GetFileIDFromOverlayID(m_ID); m_RAMAddr = m_ROM.Read32(m_OVTEntryAddr + 0x04); Byte flags = m_ROM.Read8(m_OVTEntryAddr + 0x1F); m_Data = m_ROM.ExtractFile(m_FileID); if ((flags & 0x01) == 0x01) { Jap77.Decompress(ref m_Data); } if (autorw) { m_ROM.EndRW(); } }
public NitroFile(NitroROM rom, ushort id) { if (id >= 0xF000) { throw new Exception("NitroFile: invalid file ID"); } if (Program.m_IsROMFolder) { m_ROM = rom; m_ID = id; m_Name = m_ROM.GetFileNameFromID(id); if (!m_Name.EndsWith(".narc")) { m_Data = Ndst.Helper.ReadROMFile(m_Name, Program.m_ROMBasePath, Program.m_ROMPatchPath); } return; } m_ROM = rom; m_ID = id; m_Name = m_ROM.GetFileNameFromID(id); m_Data = m_ROM.ExtractFile(m_ID); if (m_Data.Length >= 4 && Read32(0x0) == 0x37375A4C) { LZ77.Decompress(ref m_Data, true); } }
public void SetInitializer(uint address, uint size) { if (Program.m_IsROMFolder) { List <Ndst.Overlay> overlays = JsonConvert.DeserializeObject <List <Ndst.Overlay> >(NitroROM.GetExtractedLines("__ROM__/arm9Overlays.json")); Ndst.Overlay o = overlays.Where(x => x.Id == m_ID).ElementAt(0); o.StaticInitStart = address; o.StaticInitEnd = address + size; string toWrite = JsonConvert.SerializeObject(overlays, Formatting.Indented); NitroROM.WriteExtractedLines("__ROM__/arm9Overlays.json", toWrite); return; } bool autorw = !m_ROM.CanRW(); if (autorw) { m_ROM.BeginRW(); } m_ROM.Write32(m_OVTEntryAddr + 0x10, address); m_ROM.Write32(m_OVTEntryAddr + 0x14, address + size); m_ROM.m_OverlayEntries[m_ID].StaticInitStart = address; m_ROM.m_OverlayEntries[m_ID].StaticInitEnd = address + size; if (autorw) { m_ROM.EndRW(); } }
public void RemovePatch(NitroROM rom) { List <AddressDataPair> addressDataPairs = null; switch (rom.m_Version) { case NitroROM.Version.EUR: addressDataPairs = m_EURRestoreData; break; case NitroROM.Version.USA_v1: addressDataPairs = m_USv1RestoreData; break; case NitroROM.Version.USA_v2: addressDataPairs = m_USv2RestoreData; break; case NitroROM.Version.JAP: addressDataPairs = m_JAPRestoreData; break; } INitroROMBlock fileToPatch = null; if (m_FileToPatch != null) { fileToPatch = Program.m_ROM.GetFileFromName(m_FileToPatch); } else if (m_OverlayID != null) { fileToPatch = new NitroOverlay(Program.m_ROM, uint.Parse(m_OverlayID)); } foreach (AddressDataPair addressDataPair in addressDataPairs) { for (int i = 0; i < addressDataPair.m_Data.Length; i++) { if (fileToPatch == null) { rom.Write8(addressDataPair.m_Address + (uint)i, addressDataPair.m_Data[i]); } else { fileToPatch.Write8(addressDataPair.m_Address + (uint)i, addressDataPair.m_Data[i]); } } } if (fileToPatch != null) { fileToPatch.SaveChanges(); } }
public NitroFile(NitroROM rom, ushort id) { if (id >= 0xF000) throw new Exception("NitroFile: invalid file ID"); m_ROM = rom; m_ID = id; m_Name = m_ROM.GetFileNameFromID(id); m_Data = m_ROM.ExtractFile(m_ID); if (Read32(0x0) == 0x37375A4C) LZ77.Decompress(ref m_Data, true); }
public FilesystemEditorForm(MainForm main) { this.InitializeComponent(); this.Text = "Josh65536's File System Editor"; Icon = main.Icon; this.m_ROM = Program.m_ROM; ROMFileSelect.LoadFileList(this.tvFiles); this.DialogResult = DialogResult.Ignore; if (this.m_ROM.StartFilesystemEdit()) { return; } this.Close(); }
public void SaveChangesOld() { if (Program.m_IsROMFolder) { // first, ensure that the size is aligned to 4 byte boundary if (m_Data.Length % 4 != 0) { SetSize((uint)((m_Data.Length + 3) & ~3)); } List <Ndst.Overlay> overlays = JsonConvert.DeserializeObject <List <Ndst.Overlay> >(NitroROM.GetExtractedLines("__ROM__/arm9Overlays.json")); Ndst.Overlay o = overlays.Where(x => x.Id == m_ID).ElementAt(0); o.RAMSize = (uint)m_Data.Length; o.Flags &= 0xFFFFFFFE; NitroROM.WriteExtractedBytes("__ROM__/Arm9/" + m_ID + ".bin", m_Data); string toWrite = JsonConvert.SerializeObject(overlays, Formatting.Indented); NitroROM.WriteExtractedLines("__ROM__/arm9Overlays.json", toWrite); return; } bool autorw = !m_ROM.CanRW(); if (autorw) { m_ROM.BeginRW(); } // first, ensure that the size is aligned to 4 byte boundary if (m_Data.Length % 4 != 0) { SetSize((uint)((m_Data.Length + 3) & ~3)); } // reinsert file data m_ROM.ReinsertFileOld(m_FileID, m_Data); Update(); // fix overlay size m_ROM.Write32(m_OVTEntryAddr + 0x08, (uint)((m_Data.Length + 3) & ~3)); // tweak the overlay table entry byte flags = m_ROM.Read8(m_OVTEntryAddr + 0x1F); flags &= 0xFE; // [Treeki] disable compression :) m_ROM.Write8(m_OVTEntryAddr + 0x1F, flags); if (autorw) { m_ROM.EndRW(); } }
private static void LoadFiles(TreeView tvFileList, TreeNode node, NitroROM.FileEntry[] files, NARC.FileEntry[] filesNARC) { TreeNode parent = node; String[] names = new String[0]; if (files.Length == 0) { names = new String[filesNARC.Length]; for (int i = 0; i < filesNARC.Length; i++) names[i] = filesNARC[i].FullName; } else if (filesNARC.Length == 0) { names = new String[files.Length]; for (int i = 0; i < files.Length; i++) names[i] = files[i].FullName; } for (int i = 0; i < names.Length; i++) { String[] parts = names[i].Split('/'); if (parts.Length == 1) { /*if (parts[0].Equals("")) tvFiles.Nodes["root"].Nodes.Add("Overlay"); else */if (!parts[0].Equals("")) tvFileList.Nodes["root"].Nodes.Add(parts[0]).Tag = names[i]; } else { node = parent; for (int j = 0; j < parts.Length; j++) { if (!node.Nodes.ContainsKey(parts[j])) node.Nodes.Add(parts[j], parts[j]).Tag = names[i]; node = node.Nodes[parts[j]]; if (parts[j].EndsWith(".narc")) { LoadFiles(tvFileList, node, new NitroROM.FileEntry[] { }, new NARC(Program.m_ROM, Program.m_ROM.GetFileIDFromName(files[i].FullName)).GetFileEntries()); } } } } }
public NitroFile(NitroROM rom, ushort id) { if (id >= 0xF000) { throw new Exception("NitroFile: invalid file ID"); } m_ROM = rom; m_ID = id; m_Name = m_ROM.GetFileNameFromID(id); m_Data = m_ROM.ExtractFile(m_ID); if (m_Data.Length >= 4 && Read32(0x0) == 0x37375A4C) { LZ77.Decompress(ref m_Data, true); } }
public NitroOverlay(NitroROM rom, uint id) { m_ROM = rom; m_ID = id; if (Program.m_IsROMFolder) { List <Ndst.Overlay> overlays = JsonConvert.DeserializeObject <List <Ndst.Overlay> >(NitroROM.GetExtractedLines("__ROM__/arm9Overlays.json")); Ndst.Overlay o = overlays.Where(x => x.Id == id).ElementAt(0); m_FileID = o.FileId; m_RAMAddr = o.RAMAddress; m_Data = NitroROM.GetExtractedBytes("__ROM__/Arm9/" + id + ".bin"); if ((o.Flags & 0x01000000) > 0) { Jap77.Decompress(ref m_Data); } return; } bool autorw = !m_ROM.CanRW(); if (autorw) { m_ROM.BeginRW(); } m_OVTEntryAddr = m_ROM.GetOverlayEntryOffset(m_ID); m_FileID = m_ROM.GetFileIDFromOverlayID(m_ID); m_RAMAddr = m_ROM.Read32(m_OVTEntryAddr + 0x04); Byte flags = m_ROM.Read8(m_OVTEntryAddr + 0x1F); m_Data = m_ROM.ExtractFile(m_FileID); if ((flags & 0x01) == 0x01) { Jap77.Decompress(ref m_Data); } if (autorw) { m_ROM.EndRW(); } }
public NitroOverlay(NitroROM rom, uint id) { m_ROM = rom; m_ID = id; bool autorw = !m_ROM.CanRW(); if (autorw) m_ROM.BeginRW(); m_OVTEntryAddr = m_ROM.GetOverlayEntryOffset(m_ID); m_FileID = m_ROM.GetFileIDFromOverlayID(m_ID); m_RAMAddr = m_ROM.Read32(m_OVTEntryAddr + 0x04); Byte flags = m_ROM.Read8(m_OVTEntryAddr + 0x1F); m_Data = m_ROM.ExtractFile(m_FileID); if ((flags & 0x01) == 0x01) Jap77.Decompress(ref m_Data); if (autorw) m_ROM.EndRW(); }
public override void SaveChanges() { if (this.m_Data.Length % 4 != 0) { this.SetSize((uint)(this.m_Data.Length + 3 & -4)); } if (Program.m_IsROMFolder) { List <Ndst.Overlay> overlays = JsonConvert.DeserializeObject <List <Ndst.Overlay> >(NitroROM.GetExtractedLines("__ROM__/arm9Overlays.json")); Ndst.Overlay o = overlays.Where(x => x.Id == m_ID).ElementAt(0); o.RAMSize = (uint)m_Data.Length; o.Flags &= 0xFFFFFFFE; NitroROM.WriteExtractedBytes("__ROM__/Arm9/" + m_ID + ".bin", m_Data); string toWrite = JsonConvert.SerializeObject(overlays, Formatting.Indented); NitroROM.WriteExtractedLines("__ROM__/arm9Overlays.json", toWrite); return; } NitroROM.OverlayEntry[] overlayEntries = this.m_ROM.GetOverlayEntries(); NitroROM.OverlayEntry overlayEntry = overlayEntries[(int)this.m_ID]; overlayEntry.RAMSize = (uint)this.m_Data.Length; overlayEntries[(int)this.m_ID] = overlayEntry; this.m_ROM.ReinsertFile(this.m_FileID, this.m_Data); this.Update(); int num = !this.m_ROM.CanRW() ? 1 : 0; if (num != 0) { this.m_ROM.BeginRW(); } this.m_ROM.Write8(this.m_OVTEntryAddr + 31U, (byte)((uint)this.m_ROM.Read8(this.m_OVTEntryAddr + 31U) & 254U)); if (num == 0) { return; } this.m_ROM.EndRW(); }
public static bool CheckOverlayCompressed(uint id) { if (Program.m_IsROMFolder) { List <Ndst.Overlay> overlays = JsonConvert.DeserializeObject <List <Ndst.Overlay> >(NitroROM.GetExtractedLines("__ROM__/arm9Overlays.json")); Ndst.Overlay o = overlays.Where(x => x.Id == id).ElementAt(0); return((o.Flags & 0x01000000) > 0); } uint OVTEntryAddr = Program.m_ROM.GetOverlayEntryOffset(id); Byte flags = Program.m_ROM.Read8(OVTEntryAddr + 0x1F); if ((flags & 0x01) == 0x01) { return(true); } else { return(false); } }
public void RemovePatch(NitroROM rom) { List<AddressDataPair> addressDataPairs = null; switch (rom.m_Version) { case NitroROM.Version.EUR: addressDataPairs = m_EURRestoreData; break; case NitroROM.Version.USA_v1: addressDataPairs = m_USv1RestoreData; break; case NitroROM.Version.USA_v2: addressDataPairs = m_USv2RestoreData; break; case NitroROM.Version.JAP: addressDataPairs = m_JAPRestoreData; break; } INitroROMBlock fileToPatch = null; if (m_FileToPatch != null) fileToPatch = Program.m_ROM.GetFileFromName(m_FileToPatch); else if (m_OverlayID != null) fileToPatch = new NitroOverlay(Program.m_ROM, uint.Parse(m_OverlayID)); foreach (AddressDataPair addressDataPair in addressDataPairs) { for (int i = 0; i < addressDataPair.m_Data.Length; i++) { if (fileToPatch == null) { rom.Write8(addressDataPair.m_Address + (uint)i, addressDataPair.m_Data[i]); } else { fileToPatch.Write8(addressDataPair.m_Address + (uint)i, addressDataPair.m_Data[i]); } } } if (fileToPatch != null) fileToPatch.SaveChanges(); }
/* * This method takes the first Address and Data from the patch and tests if the current values in the * ROM match the values of the patch - if they match the patch is already applied. This doesn't test * all values to speed things up. */ public bool CheckIsApplied(NitroROM rom) { if (m_DecompressAllOverlays && Helper.CheckAllOverlaysDecompressed() == false) { m_IsApplied = false; return false; } INitroROMBlock fileToPatch = null; if (m_FileToPatch != null) fileToPatch = Program.m_ROM.GetFileFromName(m_FileToPatch); else if (m_OverlayID != null) fileToPatch = new NitroOverlay(Program.m_ROM, uint.Parse(m_OverlayID)); AddressDataPair testAddressDataPair = null; switch (rom.m_Version) { case NitroROM.Version.EUR: testAddressDataPair = (m_EURPatch.Count == 0) ? null : m_EURPatch.ElementAt(0); break; case NitroROM.Version.USA_v1: testAddressDataPair = (m_USv1Patch.Count == 0) ? null : m_USv1Patch.ElementAt(0); break; case NitroROM.Version.USA_v2: testAddressDataPair = (m_USv2Patch.Count == 0) ? null : m_USv2Patch.ElementAt(0); break; case NitroROM.Version.JAP: testAddressDataPair = (m_JAPPatch.Count == 0) ? null : m_JAPPatch.ElementAt(0); break; } if (testAddressDataPair == null || testAddressDataPair.m_Data == null || testAddressDataPair.m_Data.Length == 0) { m_IsApplied = false; return false; } for (int i = 0; i < testAddressDataPair.m_Data.Length; i++) { if (fileToPatch == null && rom.Read8(testAddressDataPair.m_Address + (uint)i) != testAddressDataPair.m_Data[i]) { m_IsApplied = false; return false; } else if (fileToPatch != null && fileToPatch.Read8(testAddressDataPair.m_Address + (uint)i) != testAddressDataPair.m_Data[i]) { m_IsApplied = false; return false; } } //If it reaches here, the patch has already been applied m_IsApplied = true; return true; }
/* * This method takes the first Address and Data from the patch and tests if the current values in the * ROM match the values of the patch - if they match the patch is already applied. This doesn't test * all values to speed things up. */ public bool CheckIsApplied(NitroROM rom) { if (m_DecompressAllOverlays && Helper.CheckAllOverlaysDecompressed() == false) { m_IsApplied = false; return(false); } INitroROMBlock fileToPatch = null; if (m_FileToPatch != null) { fileToPatch = Program.m_ROM.GetFileFromName(m_FileToPatch); } else if (m_OverlayID != null) { fileToPatch = new NitroOverlay(Program.m_ROM, uint.Parse(m_OverlayID)); } AddressDataPair testAddressDataPair = null; switch (rom.m_Version) { case NitroROM.Version.EUR: testAddressDataPair = (m_EURPatch.Count == 0) ? null : m_EURPatch.ElementAt(0); break; case NitroROM.Version.USA_v1: testAddressDataPair = (m_USv1Patch.Count == 0) ? null : m_USv1Patch.ElementAt(0); break; case NitroROM.Version.USA_v2: testAddressDataPair = (m_USv2Patch.Count == 0) ? null : m_USv2Patch.ElementAt(0); break; case NitroROM.Version.JAP: testAddressDataPair = (m_JAPPatch.Count == 0) ? null : m_JAPPatch.ElementAt(0); break; } if (testAddressDataPair == null || testAddressDataPair.m_Data == null || testAddressDataPair.m_Data.Length == 0) { m_IsApplied = false; return(false); } for (int i = 0; i < testAddressDataPair.m_Data.Length; i++) { if (fileToPatch == null) { if (Program.m_IsROMFolder) { Program.m_ROM.arm9R.BaseStream.Position = testAddressDataPair.m_Address + (uint)i - Program.m_ROM.headerSize; if (Program.m_ROM.arm9R.ReadByte() != testAddressDataPair.m_Data[i]) { m_IsApplied = false; return(false); } } else { if (rom.Read8(testAddressDataPair.m_Address + (uint)i) != testAddressDataPair.m_Data[i]) { m_IsApplied = false; return(false); } } } else if (fileToPatch != null && fileToPatch.Read8(testAddressDataPair.m_Address + (uint)i) != testAddressDataPair.m_Data[i]) { m_IsApplied = false; return(false); } } //If it reaches here, the patch has already been applied m_IsApplied = true; return(true); }
public Level(NitroROM rom, int id) { // }
public NARC(NitroROM rom, ushort id) : base(rom, id) { if (Program.m_IsROMFolder) { string[] files = Ndst.Helper.ReadROMLines("__ROM__/files.txt", Program.m_ROMBasePath, Program.m_ROMPatchPath); string filePath2 = ""; foreach (var f in files) { string[] fileParam = f.Split(' '); if (Ndst.Helper.ReadStringNumber(fileParam[1]) == id) { filePath2 = fileParam[0].Substring(3); } } ushort currFolderId = 1; string[] fileList = Ndst.Helper.ReadROMLines(filePath2 + ".txt", Program.m_ROMBasePath, Program.m_ROMPatchPath); Dictionary <string, Ndst.Folder> folders = new Dictionary <string, Ndst.Folder>(); Ndst.Filesystem Filesystem = new Ndst.Filesystem(); folders.Add("", Filesystem); List <FileEntry> newFiles = new List <FileEntry>(); List <DirEntry> newFolders = new List <DirEntry>(); DirEntry root2 = new DirEntry(); root2.ID = 0xF000; newFolders.Add(root2); foreach (var s in fileList) { AddFileToFilesystem(s); } m_DirEntries = newFolders.ToArray(); m_FileEntries = newFiles.ToArray(); // Add a file to the filesystem. void AddFileToFilesystem(string s) { // First get its properties. string[] fileProperties = s.Split(' '); string filePath = fileProperties[0]; if (!filePath.StartsWith("../")) { throw new Exception("ERROR: All files must be relative to parent directory \"../\""); } else { filePath = filePath.Substring(3); } // Get file ID. ushort fileId = (ushort)Ndst.Helper.ReadStringNumber(fileProperties[1]); // Proper file name and folder path. string fileName = filePath; string folderPath = ""; while (fileName.Contains('/')) { folderPath += "/" + fileName.Substring(0, fileName.IndexOf('/')); fileName = fileName.Substring(fileName.IndexOf('/') + 1); } if (folderPath.StartsWith("/")) { folderPath = folderPath.Substring(1); } // New file. Ndst.File f = new Ndst.File(); f.Name = fileName; f.Id = fileId; // Finally add the file to the folder. FileEntry fe = new FileEntry(); fe.ID = fileId; fe.Name = fileName; fe.FullName = (folderPath.Equals("") ? "" : (folderPath + "/")) + fe.Name; AddFileToFolder(f, folderPath, ref fe); } // Add a file to a folder. void AddFileToFolder(Ndst.File f, string folderPath, ref FileEntry fe) { // First check if the folder exists. if (!folders.ContainsKey(folderPath)) { AppendFolder(folderPath); } // Add the file to the folder. folders[folderPath].Files.Add(f); fe.ParentID = (ushort)(folders[folderPath].Id | 0xF000); newFiles.Add(fe); } // Append a folder. void AppendFolder(string folderPath) { string folderName = folderPath; string baseFolderPath = ""; while (folderName.Contains('/')) { baseFolderPath += "/" + folderName.Substring(0, folderName.IndexOf('/')); folderName = folderName.Substring(folderName.IndexOf('/') + 1); } if (baseFolderPath.StartsWith("/")) { baseFolderPath = baseFolderPath.Substring(1); } if (!folders.ContainsKey(baseFolderPath)) { AppendFolder(baseFolderPath); } Ndst.Folder f = new Ndst.Folder() { Id = currFolderId++, Name = folderName }; folders[baseFolderPath].Folders.Add(f); folders.Add(folderPath, f); DirEntry de = new DirEntry(); de.Name = f.Name; de.ID = (ushort)(f.Id | 0xF000); de.FullName = folderPath; de.ParentID = (ushort)(folders[baseFolderPath].Id | 0xF000); newFolders.Add(de); } return; } FATOffset = 0x1C; FATSize = Read32(0x14) - 0xC; FNTOffset = 0x1C + FATSize + 0x8; FNTSize = Read32(FNTOffset - 0x4) - 0x8; IMGOffset = FNTOffset + FNTSize + 0x8; IMGSize = Read32(IMGOffset - 0x4) - 0x8; ushort numdirs = Read16(FNTOffset + 0x6); ushort numfiles = (ushort)(FATSize / 8); m_DirEntries = new DirEntry[numdirs]; m_FileEntries = new FileEntry[numfiles]; for (ushort f = 0; f < numfiles; f++) { uint start = Read32((uint)(FATOffset + (f * 8))); uint end = Read32((uint)(FATOffset + (f * 8) + 4)); FileEntry fe; fe.ID = f; fe.ParentID = 0; fe.Offset = start; fe.Size = end - start; fe.Name = fe.FullName = ""; m_FileEntries[f] = fe; } DirEntry root; root.ID = 0xF000; root.ParentID = 0; root.Name = root.FullName = ""; m_DirEntries[0] = root; uint tableoffset = FNTOffset; for (ushort d = 0; d < numdirs; d++) { uint subtableoffset = FNTOffset + Read32(tableoffset); ushort first_fileid = Read16(tableoffset + 0x4); ushort cur_fileid = first_fileid; for (; ;) { byte type_len = Read8(subtableoffset); subtableoffset++; if (type_len == 0x00) { break; } else if (type_len > 0x80) { DirEntry dir; dir.Name = ReadString(subtableoffset, type_len & 0x7F); subtableoffset += (uint)(type_len & 0x7F); dir.ID = Read16(subtableoffset); subtableoffset += 0x2; dir.ParentID = (ushort)(d + 0xF000); dir.FullName = ""; m_DirEntries[dir.ID - 0xF000] = dir; } else if (type_len < 0x80) { m_FileEntries[cur_fileid].ParentID = (ushort)(d + 0xF000); m_FileEntries[cur_fileid].Name = ReadString(subtableoffset, type_len & 0x7F); subtableoffset += (uint)(type_len & 0x7F); cur_fileid++; } } tableoffset += 8; } for (int i = 0; i < m_DirEntries.Length; i++) { if (m_DirEntries[i].ParentID > 0xF000) { m_DirEntries[i].FullName = m_DirEntries[m_DirEntries[i].ParentID - 0xF000].FullName + "/" + m_DirEntries[i].Name; } else { m_DirEntries[i].FullName = m_DirEntries[i].Name; } } for (int i = 0; i < m_FileEntries.Length; i++) { if (m_FileEntries[i].ParentID > 0xF000) { m_FileEntries[i].FullName = m_DirEntries[m_FileEntries[i].ParentID - 0xF000].FullName + "/" + m_FileEntries[i].Name; } else { m_FileEntries[i].FullName = m_FileEntries[i].Name; } } }
public void ApplyPatch(NitroROM rom) { Program.m_ROM.BeginRW(); List <AddressDataPair> addressDataPairs = null; switch (rom.m_Version) { case NitroROM.Version.EUR: addressDataPairs = m_EURPatch; m_EURRestoreData = GenerateRestoreData(m_EURPatch); break; case NitroROM.Version.USA_v1: addressDataPairs = m_USv1Patch; m_USv1RestoreData = GenerateRestoreData(m_USv1Patch); break; case NitroROM.Version.USA_v2: addressDataPairs = m_USv2Patch; m_USv2RestoreData = GenerateRestoreData(m_USv2Patch); break; case NitroROM.Version.JAP: addressDataPairs = m_JAPPatch; m_JAPRestoreData = GenerateRestoreData(m_JAPPatch); break; } if (m_DecompressAllOverlays) { Helper.DecompressOverlaysWithinGame(); } if (m_FileToPatch != null) { NitroFile myFile = Program.m_ROM.GetFileFromName(m_FileToPatch); foreach (AddressDataPair addressDataPair in addressDataPairs) { for (int i = 0; i < addressDataPair.m_Data.Length; i++) { myFile.Write8(addressDataPair.m_Address + (uint)i, addressDataPair.m_Data[i]); } } Program.m_ROM.EndRW(); myFile.SaveChanges(); return; } INitroROMBlock fileToPatch = null; if (m_FileToPatch != null) { fileToPatch = Program.m_ROM.GetFileFromName(m_FileToPatch); } else if (m_OverlayID != null) { fileToPatch = new NitroOverlay(Program.m_ROM, uint.Parse(m_OverlayID)); } foreach (AddressDataPair addressDataPair in addressDataPairs) { for (int i = 0; i < addressDataPair.m_Data.Length; i++) { if (fileToPatch == null) { if (Program.m_IsROMFolder) { Program.m_ROM.arm9W.BaseStream.Position = addressDataPair.m_Address + (uint)i - Program.m_ROM.headerSize; Program.m_ROM.arm9W.Write(addressDataPair.m_Data[i]); } else { rom.Write8(addressDataPair.m_Address + (uint)i, addressDataPair.m_Data[i]); } } else { fileToPatch.Write8(addressDataPair.m_Address + (uint)i, addressDataPair.m_Data[i]); } } } Program.m_ROM.EndRW(); if (fileToPatch != null) { fileToPatch.SaveChanges(); } }
public NARC(NitroROM rom, ushort id) : base(rom, id) { FATOffset = 0x1C; FATSize = Read32(0x14) - 0xC; FNTOffset = 0x1C + FATSize + 0x8; FNTSize = Read32(FNTOffset - 0x4) - 0x8; IMGOffset = FNTOffset + FNTSize + 0x8; IMGSize = Read32(IMGOffset - 0x4) - 0x8; ushort numdirs = Read16(FNTOffset + 0x6); ushort numfiles = (ushort)(FATSize / 8); m_DirEntries = new DirEntry[numdirs]; m_FileEntries = new FileEntry[numfiles]; for (ushort f = 0; f < numfiles; f++) { uint start = Read32((uint)(FATOffset + (f*8))); uint end = Read32((uint)(FATOffset + (f*8) + 4)); FileEntry fe; fe.ID = f; fe.ParentID = 0; fe.Offset = start; fe.Size = end - start; fe.Name = fe.FullName = ""; m_FileEntries[f] = fe; } DirEntry root; root.ID = 0xF000; root.ParentID = 0; root.Name = root.FullName = ""; m_DirEntries[0] = root; uint tableoffset = FNTOffset; for (ushort d = 0; d < numdirs; d++) { uint subtableoffset = FNTOffset + Read32(tableoffset); ushort first_fileid = Read16(tableoffset + 0x4); ushort cur_fileid = first_fileid; for (; ; ) { byte type_len = Read8(subtableoffset); subtableoffset++; if (type_len == 0x00) break; else if (type_len > 0x80) { DirEntry dir; dir.Name = ReadString(subtableoffset, type_len & 0x7F); subtableoffset += (uint)(type_len & 0x7F); dir.ID = Read16(subtableoffset); subtableoffset += 0x2; dir.ParentID = (ushort)(d + 0xF000); dir.FullName = ""; m_DirEntries[dir.ID - 0xF000] = dir; } else if (type_len < 0x80) { m_FileEntries[cur_fileid].ParentID = (ushort)(d + 0xF000); m_FileEntries[cur_fileid].Name = ReadString(subtableoffset, type_len & 0x7F); subtableoffset += (uint)(type_len & 0x7F); cur_fileid++; } } tableoffset += 8; } for (int i = 0; i < m_DirEntries.Length; i++) { if (m_DirEntries[i].ParentID > 0xF000) m_DirEntries[i].FullName = m_DirEntries[m_DirEntries[i].ParentID - 0xF000].FullName + "/" + m_DirEntries[i].Name; else m_DirEntries[i].FullName = m_DirEntries[i].Name; } for (int i = 0; i < m_FileEntries.Length; i++) { if (m_FileEntries[i].ParentID > 0xF000) m_FileEntries[i].FullName = m_DirEntries[m_FileEntries[i].ParentID - 0xF000].FullName + "/" + m_FileEntries[i].Name; else m_FileEntries[i].FullName = m_FileEntries[i].Name; } }
public NARC(NitroROM rom, ushort id) : base(rom, id) { FATOffset = 0x1C; FATSize = Read32(0x14) - 0xC; FNTOffset = 0x1C + FATSize + 0x8; FNTSize = Read32(FNTOffset - 0x4) - 0x8; IMGOffset = FNTOffset + FNTSize + 0x8; IMGSize = Read32(IMGOffset - 0x4) - 0x8; ushort numdirs = Read16(FNTOffset + 0x6); ushort numfiles = (ushort)(FATSize / 8); m_DirEntries = new DirEntry[numdirs]; m_FileEntries = new FileEntry[numfiles]; for (ushort f = 0; f < numfiles; f++) { uint start = Read32((uint)(FATOffset + (f * 8))); uint end = Read32((uint)(FATOffset + (f * 8) + 4)); FileEntry fe; fe.ID = f; fe.ParentID = 0; fe.Offset = start; fe.Size = end - start; fe.Name = fe.FullName = ""; m_FileEntries[f] = fe; } DirEntry root; root.ID = 0xF000; root.ParentID = 0; root.Name = root.FullName = ""; m_DirEntries[0] = root; uint tableoffset = FNTOffset; for (ushort d = 0; d < numdirs; d++) { uint subtableoffset = FNTOffset + Read32(tableoffset); ushort first_fileid = Read16(tableoffset + 0x4); ushort cur_fileid = first_fileid; for (; ;) { byte type_len = Read8(subtableoffset); subtableoffset++; if (type_len == 0x00) { break; } else if (type_len > 0x80) { DirEntry dir; dir.Name = ReadString(subtableoffset, type_len & 0x7F); subtableoffset += (uint)(type_len & 0x7F); dir.ID = Read16(subtableoffset); subtableoffset += 0x2; dir.ParentID = (ushort)(d + 0xF000); dir.FullName = ""; m_DirEntries[dir.ID - 0xF000] = dir; } else if (type_len < 0x80) { m_FileEntries[cur_fileid].ParentID = (ushort)(d + 0xF000); m_FileEntries[cur_fileid].Name = ReadString(subtableoffset, type_len & 0x7F); subtableoffset += (uint)(type_len & 0x7F); cur_fileid++; } } tableoffset += 8; } for (int i = 0; i < m_DirEntries.Length; i++) { if (m_DirEntries[i].ParentID > 0xF000) { m_DirEntries[i].FullName = m_DirEntries[m_DirEntries[i].ParentID - 0xF000].FullName + "/" + m_DirEntries[i].Name; } else { m_DirEntries[i].FullName = m_DirEntries[i].Name; } } for (int i = 0; i < m_FileEntries.Length; i++) { if (m_FileEntries[i].ParentID > 0xF000) { m_FileEntries[i].FullName = m_DirEntries[m_FileEntries[i].ParentID - 0xF000].FullName + "/" + m_FileEntries[i].Name; } else { m_FileEntries[i].FullName = m_FileEntries[i].Name; } } }