/// <summary> /// Write the Fat to a stream. /// </summary> /// <param name="str">Stream to write to.</param> public override void Write(DataStream str) { DataWriter dw = new DataWriter(str); uint offset = (uint)str.Position + this.Size + this.firstOffset; offset = offset.Pad(FileSystem.PaddingAddress); foreach (GameFile file in this.files) { OverlayFile overlay = file as OverlayFile; if (overlay == null) { dw.Write(offset); // Start offset offset += (uint)file.Length; dw.Write(offset); // End offset } else { dw.Write(overlay.WriteAddress); dw.Write((uint)(overlay.WriteAddress + overlay.Length)); } offset = offset.Pad(FileSystem.PaddingAddress); // Pad offset } }
/// <summary> /// Create a new overlay file from the info in the overlay table. /// </summary> /// <param name="str">Stream to read the table.</param> /// <param name="listFiles">List of files where the overlay must be.</param> /// <returns>Overlay file.</returns> public static OverlayFile FromTable(DataStream str, bool isArm9, GameFile[] listFiles) { DataReader dr = new DataReader(str); str.Seek(0x18, SeekMode.Current); uint fileId = dr.ReadUInt32(); str.Seek(-0x1C, SeekMode.Current); OverlayFile overlay = new OverlayFile(listFiles[fileId], isArm9); overlay.OverlayId = dr.ReadUInt32(); overlay.RamAddress = dr.ReadUInt32(); overlay.RamSize = dr.ReadUInt32(); overlay.BssSize = dr.ReadUInt32(); overlay.StaticInitStart = dr.ReadUInt32(); overlay.StaticInitEnd = dr.ReadUInt32(); dr.ReadUInt32(); // File ID again uint encodingInfo = dr.ReadUInt32(); overlay.EncodedSize = encodingInfo & 0x00FFFFFF; overlay.IsEncoded = ((encodingInfo >> 24) & 0x01) == 1; overlay.IsSigned = ((encodingInfo >> 24) & 0x02) == 2; return(overlay); }
/// <summary> /// Write the table of overlays info. /// </summary> /// <param name="str">Stream to write to.</param> /// <param name="header">Header of the ROM to update.</param> /// <param name="shiftOffset">Amount of data before the current stream.</param> public void WriteTable(DataStream str, RomHeader header, uint shiftOffset) { long startOffset = str.Position; int numOverlays = 0; // For each overlay, writes its info foreach (GameFile file in this.Files) { OverlayFile ov = file as OverlayFile; if (ov == null) { continue; } ov.WriteTable(str); numOverlays++; } // Updates RomHeader if (this.isArm9) { header.Ov9TableSize = (uint)(numOverlays * OverlayFile.TableEntrySize); if (numOverlays > 0) { header.Ov9TableOffset = (uint)(shiftOffset + startOffset); } else { header.Ov9TableOffset = 0x00; } } else { header.Ov7TableSize = (uint)(numOverlays * OverlayFile.TableEntrySize); if (numOverlays > 0) { header.Ov7TableOffset = (uint)(shiftOffset + startOffset); } else { header.Ov7TableOffset = 0x00; } } }
private void WriteArm(DataStream str, bool isArm9) { // Write the ARM file. foreach (GameFile file in this.sysFolder.Files) { ArmFile arm = file as ArmFile; if (arm == null || arm.IsArm9 != isArm9) { continue; } // Writes to this Stream but sets the its address after RomHeader arm.UpdateAndWrite(str, this.header, this.header.HeaderSize); str.WritePadding(FileSystem.PaddingByte, FileSystem.PaddingAddress); } // Writes the overlay table and overlays foreach (GameFolder folder in this.sysFolder.Folders) { OverlayFolder overlayFolder = folder as OverlayFolder; if (overlayFolder == null || overlayFolder.IsArm9 != isArm9) { continue; } // Writes overlay info overlayFolder.WriteTable(str, this.header, this.header.HeaderSize); str.WritePadding(FileSystem.PaddingByte, FileSystem.PaddingAddress); // Write overlays foreach (GameFile file in overlayFolder.Files) { OverlayFile overlay = file as OverlayFile; if (overlay == null) { continue; } overlay.WriteAddress = (uint)(this.header.HeaderSize + str.Position); overlay.Stream.WriteTo(str); str.WritePadding(FileSystem.PaddingByte, FileSystem.PaddingAddress); } } }
/// <summary> /// Create a folder with all the overlays of the same ARM. /// </summary> /// <param name="str">Stream to read the overlay table.</param> /// <param name="header">Header of the current ROM.</param> /// <param name="isArm9">If must read overlays from the ARM9 or ARM7.</param> /// <param name="listFiles">List with all the files in the ROM.</param> /// <returns>Folder with overlays.</returns> public static OverlayFolder FromTable(DataStream str, RomHeader header, bool isArm9, GameFile[] listFiles) { OverlayFolder overlays = new OverlayFolder(isArm9); int numOverlays; if (isArm9) { str.Seek(header.Ov9TableOffset, SeekMode.Origin); numOverlays = (int)(header.Ov9TableSize / OverlayFile.TableEntrySize); } else { str.Seek(header.Ov7TableOffset, SeekMode.Origin); numOverlays = (int)(header.Ov7TableSize / OverlayFile.TableEntrySize); } for (int i = 0; i < numOverlays; i++) { overlays.AddFile(OverlayFile.FromTable(str, isArm9, listFiles)); } return(overlays); }
/// <summary> /// Create a new overlay file from the info in the overlay table. /// </summary> /// <param name="str">Stream to read the table.</param> /// <param name="listFiles">List of files where the overlay must be.</param> /// <returns>Overlay file.</returns> public static OverlayFile FromTable(DataStream str, bool isArm9, GameFile[] listFiles) { DataReader dr = new DataReader(str); str.Seek(0x18, SeekMode.Current); uint fileId = dr.ReadUInt32(); str.Seek(-0x1C, SeekMode.Current); OverlayFile overlay = new OverlayFile(listFiles[fileId], isArm9); overlay.OverlayId = dr.ReadUInt32(); overlay.RamAddress = dr.ReadUInt32(); overlay.RamSize = dr.ReadUInt32(); overlay.BssSize = dr.ReadUInt32(); overlay.StaticInitStart = dr.ReadUInt32(); overlay.StaticInitEnd = dr.ReadUInt32(); dr.ReadUInt32(); // File ID again uint encodingInfo = dr.ReadUInt32(); overlay.EncodedSize = encodingInfo & 0x00FFFFFF; overlay.IsEncoded = ((encodingInfo >> 24) & 0x01) == 1; overlay.IsSigned = ((encodingInfo >> 24) & 0x02) == 2; return overlay; }