/// <summary> /// Create the folder tree. /// </summary> /// <param name="files">Files in the tree.</param> /// <returns>Root folder</returns> public GameFolder CreateTree(GameFile[] files) { GameFolder root = new GameFolder("ROM"); root.Tags["Id"] = (ushort)this.tables.Length; this.CreateTree(root, files); return root; }
public static GameFolder FromPath(string dir, string dirName) { GameFolder folder = new GameFolder(dirName); foreach (string filePath in Directory.GetFiles(dir)) { string filename = Path.GetFileName(filePath); DataStream stream = new DataStream(filePath, FileMode.Open, FileAccess.ReadWrite); folder.AddFile(new GameFile(filename, stream)); } return folder; }
private static void TestNdsRomRead(string romPath, string filePath, string outPath) { DataStream romStream = new DataStream(romPath, FileMode.Open, FileAccess.Read); Format romFormat = FileManager.GetFormat("Rom"); GameFolder main = new GameFolder("main"); GameFile rom = new GameFile(Path.GetFileName(romPath), romStream, romFormat); main.AddFile(rom); romFormat.Initialize(rom); XDocument xmlGame = new XDocument(); // TODO: Replace with ExampleGame.xml xmlGame.Add(new XElement("GameInfo", new XElement("Files"))); FileManager.Initialize(main, FileInfoCollection.FromXml(xmlGame)); GameFile file = FileManager.GetInstance().RescueFile(filePath); if (file != null) file.Stream.WriteTo(outPath); romStream.Dispose(); }
private void CreateTree(GameFolder currentFolder, GameFile[] listFile) { int folderId = ((ushort)currentFolder.Tags["Id"] > 0x0FFF) ? (ushort)currentFolder.Tags["Id"] & 0x0FFF : 0; // Add files foreach (ElementInfo fileInfo in this.tables[folderId].Files) { listFile[fileInfo.Id].Name = fileInfo.Name; currentFolder.AddFile(listFile[fileInfo.Id]); } // Add subfolders foreach (ElementInfo folderInfo in this.tables[folderId].Folders) { GameFolder subFolder = new GameFolder(folderInfo.Name); subFolder.Tags["Id"] = folderInfo.Id; this.CreateTree(subFolder, listFile); currentFolder.AddFolder(subFolder); } }
private void CreateTablesRecursive(GameFolder currentFolder, ushort parentId, ref uint subtablesOffset) { int folderId = ((ushort)currentFolder.Tags["Id"] > 0x0FFF) ? (ushort)currentFolder.Tags["Id"] & 0x0FFF : 0; this.tables[folderId] = new Fnt.FntTable( subtablesOffset, GetIdFirstFile(currentFolder), parentId); // Set the info values foreach (GameFile file in currentFolder.Files) this.tables[folderId].AddFileInfo(file.Name, (ushort)file.Tags["Id"]); foreach (GameFolder folder in currentFolder.Folders) this.tables[folderId].AddFolderInfo(folder.Name, (ushort)folder.Tags["Id"]); subtablesOffset += (uint)this.tables[folderId].GetInfoSize(); foreach (GameFolder folder in currentFolder.Folders) this.CreateTablesRecursive(folder, (ushort)(0xF000 | folderId), ref subtablesOffset); }
private void CreateTables(GameFolder root, int firstId) { int numDirs = CountDirectories(root) + 1; this.tables = new Fnt.FntTable[numDirs]; ReassignFileIds(root, firstId); // For each directory create its table. uint subtableOffset = (uint)(this.tables.Length * Fnt.FntTable.MainTableSize); this.CreateTablesRecursive(root, (ushort)numDirs, ref subtableOffset); }
private static int ReassignFileIds(GameFolder folder, int currentId) { foreach (GameFile file in folder.Files) file.Tags["Id"] = (ushort)(currentId++); foreach (GameFolder subfolder in folder.Folders) currentId = ReassignFileIds(subfolder, currentId); return currentId; }
private static ushort GetIdFirstFile(GameFolder folder) { ushort id = 0xFFFF; // Searchs in files foreach (GameFile file in folder.Files) { if ((ushort)file.Tags["Id"] < id) id = (ushort)file.Tags["Id"]; } // Searchs in subfolders foreach (GameFolder subfolder in folder.Folders) { ushort fId = GetIdFirstFile(subfolder); if (fId < id) id = fId; } return id; }
private static int CountDirectories(GameFolder folder) { int numDirs = folder.Folders.Count; foreach (GameFolder subfolder in folder.Folders) numDirs += CountDirectories(subfolder); return numDirs; }
/// <summary> /// Write the file system to the stream. /// </summary> /// <param name="str">Stream to write to.</param> public override void Write(DataStream str) { // The order is: ARM9 - Overlays9 - ARM7 - Overlays7 - FNT - FAT this.WriteArm(str, true); // Write ARM9 this.WriteArm(str, false); // Write ARM7 // To get the first ROM file ID int numOverlays = this.CountOverlays(false) + this.CountOverlays(true); // Create a new File Name Table... Fnt fnt = new Fnt(); fnt.Initialize(null, this.root, numOverlays); // ... and writes it this.header.FntOffset = (uint)(this.header.HeaderSize + str.Position); long fntStartOffset = str.Position; fnt.Write(str); this.header.FntSize = (uint)(str.Position - fntStartOffset); str.WritePadding(FileSystem.PaddingByte, FileSystem.PaddingAddress); // Create a temp dir with every file to be register in the FAT (Game + System) GameFolder tmpFolder = new GameFolder(string.Empty); tmpFolder.AddFolders(this.sysFolder.Folders); // Overlay folders tmpFolder.AddFolder(this.root); // Game files // Write File Allocation Table Fat fat = new Fat(); fat.Initialize(null, tmpFolder, Banner.Size + this.header.HeaderSize); // First file offset after banner this.header.FatOffset = (uint)(this.header.HeaderSize + str.Position); fat.Write(str); str.WritePadding(FileSystem.PaddingByte, FileSystem.PaddingAddress); this.header.FatSize = fat.Size; }
/// <summary> /// Read the file system of the ROM and create the folder tree. /// </summary> /// <param name="str">Stream to read the file system.</param> public override void Read(DataStream str) { // Read File Allocation Table // I'm creating a new DataStream variable because Fat class needs to know its length. DataStream fatStr = new DataStream(str, this.header.FatOffset, this.header.FatSize); Fat fat = new Fat(); fat.Read(fatStr); fatStr.Dispose(); // Read File Name Table str.Seek(header.FntOffset, SeekMode.Origin); Fnt fnt = new Fnt(); fnt.Read(str); // Get root folder this.root = fnt.CreateTree(fat.GetFiles()); // Get ARM and Overlay files this.sysFolder = new GameFolder("System"); this.sysFolder.AddFile(ArmFile.FromStream(str, this.header, true)); this.sysFolder.AddFolder(OverlayFolder.FromTable(str, this.header, true, fat.GetFiles())); this.sysFolder.AddFile(ArmFile.FromStream(str, this.header, false)); this.sysFolder.AddFolder(OverlayFolder.FromTable(str, this.header, false, fat.GetFiles())); }