public void SaveChanges() { //using a MemoryStream instead of an INitroROMBlock for dynamic size MemoryStream stream = new MemoryStream(); BinaryWriter binWriter = new BinaryWriter(stream); byte overlayInitialiserVersion = 0; switch (Program.m_ROM.m_Version) { case NitroROM.Version.EUR: binWriter.Write(Properties.Resources.level_ovl_init_EUR_001); overlayInitialiserVersion = 1; break; case NitroROM.Version.USA_v1: binWriter.Write(Properties.Resources.level_ovl_init_USAv1); break; case NitroROM.Version.USA_v2: binWriter.Write(Properties.Resources.level_ovl_init_USAv2); break; case NitroROM.Version.JAP: binWriter.Write(Properties.Resources.level_ovl_init_JAP); break; default: throw new InvalidDataException("This ROM is an unknown version."); } m_LevelSettings.LevelFormatVersion = k_LevelFormatVersion; m_LevelSettings.OverlayInitialiserVersion = overlayInitialiserVersion; uint areaTableOffset; m_LevelSettings.SaveChanges(binWriter); SaveCLPS(binWriter); SaveMiscObjs(binWriter); SaveRegularObjs(binWriter, out areaTableOffset); LevelTexAnim.SaveAll(binWriter, m_TexAnims, areaTableOffset, (uint)m_NumAreas); if (DoesLevelSupportDynamicLibs()) { while (stream.Position % 2 != 0) { binWriter.Write((byte)0); } Helper.WritePosAndRestore(binWriter, 0x30, 0); binWriter.Write((ushort)m_DynLibIDs.Count); m_DynLibIDs.ForEach(x => binWriter.Write((ushort)x)); Helper.AlignWriter(binWriter, 4); } Array.Clear(m_Overlay.m_Data, 0, m_Overlay.m_Data.Length); Array.Resize(ref m_Overlay.m_Data, (int)stream.Length); stream.Position = 0; new BinaryReader(stream).Read(m_Overlay.m_Data, 0, (int)stream.Length); m_Overlay.SaveChanges(); }
private void SaveObjList(BinaryWriter binWriter, IEnumerable <LevelObject> objList, LevelObject.Type[] typeOrder) { IEnumerable <IGrouping <int, LevelObject> > objGroups = objList .Where(x => Array.Exists(typeOrder, y => y == x.m_Type)) .GroupBy(x => (int)x.m_Type | (int)x.m_Layer << 5); binWriter.Write(objGroups.Count()); binWriter.Write((uint)(binWriter.BaseStream.Position + 4 + Program.m_ROM.LevelOvlOffset)); uint basePos = (uint)binWriter.BaseStream.Position; binWriter.Write(new byte[8 * objGroups.Count()]); uint i = 0; //This below is a very important order. //Not following it could result in objects being initialized in the wrong order. //For example, if 1 came before 4, the camera wouldn't be initialized properly. foreach (int type in typeOrder) { foreach (IGrouping <int, LevelObject> group in objGroups.Where(x => (x.Key & 0x1f) == type)) { uint oldPos = (uint)binWriter.BaseStream.Position; binWriter.BaseStream.Position = basePos + 8 * i; binWriter.Write((byte)group.Key); binWriter.Write((byte)group.Count()); binWriter.Write((ushort)0); binWriter.Write(oldPos + Program.m_ROM.LevelOvlOffset); binWriter.BaseStream.Position = oldPos; if (type == (int)LevelObject.Type.PATH_NODE) { group.OrderBy(obj => ((PathPointObject)obj).m_NodeID).ToList().ForEach(x => x.SaveChanges(binWriter)); } else { group.ToList().ForEach(x => x.SaveChanges(binWriter)); } Helper.AlignWriter(binWriter, 4); ++i; } } }
public void SaveFilesystem() { MemoryStream memoryStream = new MemoryStream(); BinaryWriter binWriter = new BinaryWriter((Stream)memoryStream, Encoding.ASCII); List <NitroROM.FileEntry> list1 = ((IEnumerable <NitroROM.FileEntry>) this.m_FileEntries).ToList <NitroROM.FileEntry>(); list1.RemoveAll((Predicate <NitroROM.FileEntry>)(x => x.Name == "")); list1.Sort((Comparison <NitroROM.FileEntry>)((x, y) => { if ((int)x.ParentID > (int)y.ParentID) { return(1); } return((int)x.ParentID >= (int)y.ParentID ? string.Compare(x.Name, y.Name) : -1); })); this.m_BinReader.BaseStream.Position = 0L; binWriter.Write(this.m_BinReader.ReadBytes(16384)); this.m_BinReader.BaseStream.Position = 44L; int count = this.m_BinReader.ReadInt32(); this.m_BinReader.BaseStream.Position = 16384L; binWriter.Write(this.m_BinReader.ReadBytes(count)); int position1 = (int)binWriter.BaseStream.Position; binWriter.BaseStream.Position = 48L; binWriter.Write(position1); this.m_BinReader.BaseStream.Position = 48L; int num1 = this.m_BinReader.ReadInt32(); binWriter.BaseStream.Position = (long)position1; this.m_BinReader.BaseStream.Position = (long)num1; binWriter.Write(this.m_BinReader.ReadBytes(150308)); int[] numArray1 = new int[this.m_OverlayEntries.Length + list1.Count]; int[] numArray2 = new int[this.m_OverlayEntries.Length + list1.Count]; numArray1[0] = (int)binWriter.BaseStream.Position; int length = list1.Max <NitroROM.FileEntry>((Func <NitroROM.FileEntry, int>)(x => x.InternalID != ushort.MaxValue ? (int)x.InternalID : 0)) + 1; NitroOverlay nitroOverlay = new NitroOverlay(this, 0U); int position2 = (int)binWriter.BaseStream.Position; binWriter.Write(nitroOverlay.ReadBlock(0U, 156U)); binWriter.Write(length); binWriter.Write(nitroOverlay.Read32(160U)); binWriter.Write(uint.MaxValue); binWriter.Write(nitroOverlay.ReadBlock(168U, 24U)); int[] numArray3 = new int[length]; for (int index = 0; index < list1.Count; ++index) { if (list1[index].InternalID != ushort.MaxValue) { numArray3[(int)list1[index].InternalID] = (int)binWriter.BaseStream.Position - position2 + 34251808; binWriter.Write((list1[index].FullName + "\0").ToCharArray()); Helper.AlignWriter(binWriter, 4U); } } Helper.WritePosAndRestore(binWriter, (uint)(position2 + 164), (uint)(34251808 - position2)); foreach (int num2 in numArray3) { binWriter.Write(num2); } numArray2[0] = (int)binWriter.BaseStream.Position; for (int index = 1; index < this.m_OverlayEntries.Length; ++index) { numArray1[index] = (int)binWriter.BaseStream.Position; NitroROM.FileEntry fileEntry = this.m_FileEntries[(int)this.m_OverlayEntries[index].FileID]; if (fileEntry.Data != null) { binWriter.Write(fileEntry.Data); } else { this.m_BinReader.BaseStream.Position = (long)fileEntry.Offset; binWriter.Write(this.m_BinReader.ReadBytes((int)fileEntry.Size)); } numArray2[index] = (int)binWriter.BaseStream.Position; Helper.AlignWriter(binWriter, 4U); } Helper.WritePosAndRestore(binWriter, 80U, 0U); for (int index = 0; index < this.m_OverlayEntries.Length; ++index) { binWriter.Write(index); binWriter.Write(this.m_OverlayEntries[index].RAMAddress); binWriter.Write(this.m_OverlayEntries[index].RAMSize); binWriter.Write(this.m_OverlayEntries[index].BSSSize); binWriter.Write(this.m_OverlayEntries[index].StaticInitStart); binWriter.Write(this.m_OverlayEntries[index].StaticInitEnd); binWriter.Write(index); binWriter.Write((uint)((long)this.m_OverlayEntries[index].Flags & (long)~(index == 0 ? 16777216 : 0))); } for (int index = 0; index < list1.Count; ++index) { numArray1[index + this.m_OverlayEntries.Length] = (int)binWriter.BaseStream.Position; if (list1[index].Data != null) { binWriter.Write(list1[index].Data); NitroROM.FileEntry fileEntry = list1[index]; fileEntry.Data = (byte[])null; list1[index] = fileEntry; } else { this.m_BinReader.BaseStream.Position = (long)list1[index].Offset; binWriter.Write(this.m_BinReader.ReadBytes((int)list1[index].Size)); } numArray2[index + this.m_OverlayEntries.Length] = (int)binWriter.BaseStream.Position; Helper.AlignWriter(binWriter, 4U); } int position3 = (int)binWriter.BaseStream.Position; binWriter.Write(new byte[8 * this.m_DirEntries.Length]); int[] numArray4 = new int[this.m_DirEntries.Length]; List <NitroROM.DirEntry> list2 = ((IEnumerable <NitroROM.DirEntry>) this.m_DirEntries).ToList <NitroROM.DirEntry>(); list2.RemoveAt(0); list2.Sort((Comparison <NitroROM.DirEntry>)((x, y) => { if ((int)x.ParentID > (int)y.ParentID) { return(1); } return((int)x.ParentID >= (int)y.ParentID ? string.Compare(x.Name, y.Name) : -1); })); int index1 = 0; int index2 = 0; for (int index3 = 0; index3 < this.m_DirEntries.Length; ++index3) { numArray4[index3] = (int)binWriter.BaseStream.Position - position3; for (; index1 < list1.Count && (int)list1[index1].ParentID == index3 + 61440; ++index1) { binWriter.Write((byte)list1[index1].Name.Length); binWriter.Write(list1[index1].Name.ToCharArray()); } for (; index2 < list2.Count && (int)list2[index2].ParentID == index3 + 61440; ++index2) { binWriter.Write((byte)(list2[index2].Name.Length + 128)); binWriter.Write(list2[index2].Name.ToCharArray()); binWriter.Write(list2[index2].ID); } binWriter.Write((byte)0); } Helper.AlignWriter(binWriter, 4U); int position4 = (int)binWriter.BaseStream.Position; binWriter.BaseStream.Position = (long)position3; int index4 = 0; for (int index3 = 0; index3 < this.m_DirEntries.Length; ++index3) { binWriter.Write(numArray4[index3]); binWriter.Write((ushort)(index4 + this.m_OverlayEntries.Length)); if (index3 == 0) { binWriter.Write((ushort)this.m_DirEntries.Length); } else { binWriter.Write(this.m_DirEntries[index3].ParentID); } while (index4 < list1.Count && (int)list1[index4].ParentID == index3 + 61440) { ++index4; } } binWriter.BaseStream.Position = (long)position4; for (int index3 = 0; index3 < numArray1.Length; ++index3) { binWriter.Write(numArray1[index3]); binWriter.Write(numArray2[index3]); } int position5 = (int)binWriter.BaseStream.Position; binWriter.BaseStream.Position = 64L; binWriter.Write(position3); binWriter.Write(position4 - position3); binWriter.Write(position4); binWriter.Write(position5 - position4); binWriter.BaseStream.Position = 20L; byte num3 = 0; int num4 = position5; while (num4 > 131072) { num4 >>= 1; ++num3; } binWriter.Write(num3); binWriter.BaseStream.Position = 128L; binWriter.Write(position5); this.m_FileStream.Close(); this.m_FileStream = (Stream)memoryStream; this.m_BinReader = new BinaryReader(this.m_FileStream, Encoding.ASCII); this.m_BinWriter = binWriter; this.FixCRC16(); this.AllowEmptySpaceInOv0(); this.m_BinWriter.BaseStream.SetLength((long)position5); this.EndRW(true); this.LoadROM(this.m_Path); }