/// <summary> /// injects bytes in the globaldata ROM /// </summary> /// <param name="TableID">The filetable to instert into</param> /// <param name="FileID">The FileID</param> /// <param name="Data">Uncompressed filedata to insert</param> /// <returns>Returns ROM with custom file</returns> public byte[] InjectIntoROM(int TableID, int FileID, byte[] Data) { byte[] ROM = GlobalData.Instance.ROM; int FileTableOffset = GlobalData.Instance.ftable_arr[TableID]; byte[] CompressedData = Compression.Compression.CompressInflate(Data); int[] TableOffsets = GlobalData.Instance.ftable_arr; int Offset = TableOffsets[TableID] + 0x10; Offset += FileID * 8; UInt32 FileOffset = ByteTools.Read4Bytes(ROM, (UInt32)Offset) + (UInt32)TableOffsets[TableID] + 0x2008; int CompressedSize = CompressedData.Length - 1; int UnCompressedSize = Data.Length - 1; //check if compressed data fits within ROM, if not, expand /* #region CheckIfFit * int LastOffset = GlobalData.Instance.ftable_arr[GlobalData.Instance.ftable_arr.Length - 1] + 0x10; * UInt32 BiggestOffset = 0; * while (ByteTools.Read4Bytes(ROM, ROM[LastOffset]) != 0xFFFFFFFF) * { * UInt32 CurOffset = ByteTools.Read4Bytes(ROM, ROM[LastOffset]); * if (CurOffset > BiggestOffset) * { * BiggestOffset = CurOffset; * } * LastOffset += 8; * } * BiggestOffset += (UInt32)GlobalData.Instance.ftable_arr[GlobalData.Instance.ftable_arr.Length - 1]; * byte[] RomBuf = new byte[BiggestOffset]; * Array.Copy(ROM, 0, RomBuf, 0, BiggestOffset); * if(RomBuf.Length - 1 + CompressedSize > ROM.Length - 1) * { * ROM = ByteTools.Extend4MB(ROM); * } #endregion */ //going to assume last file = final offset UInt32 OrigCompSize = ByteTools.Read4Bytes(ROM, (uint)Offset + 4); UInt32 LastIndex = 0x301B48; UInt32 LastCompression = ByteTools.Read4Bytes(ROM, LastIndex + 4); UInt32 LastUsedAddr = ByteTools.Read4Bytes(ROM, LastIndex) + LastCompression; if (LastUsedAddr + Math.Abs(OrigCompSize - CompressedSize) > ROM.Length) { ROM = ByteTools.Extend4MB(ROM); } List <byte> RomL = new List <byte>(); RomL.AddRange(ROM); //get original compressed size and take out old data CompressedSize += 4; //compensation for first 4 bytes //get rid of original data RomL.RemoveRange((int)FileOffset, (int)OrigCompSize); //insert new data byte[] buf = BitConverter.GetBytes(UnCompressedSize); if (BitConverter.IsLittleEndian) { Array.Reverse(buf); } RomL.InsertRange((int)FileOffset, buf); RomL.InsertRange((int)FileOffset + 4, CompressedData); //other offsets are still not correct //fix overwritten file sizes buf = BitConverter.GetBytes(CompressedSize); if (BitConverter.IsLittleEndian) { Array.Reverse(buf); } RomL.RemoveRange(Offset + 4, 4); RomL.InsertRange(Offset + 4, buf); //fix all other offsets int BufOffset = Offset + 8; while (ByteTools.Read4Bytes(ROM, (uint)BufOffset) != 0xFFFFFFFF) { int OffsetToChange = (int)OrigCompSize - ((int)CompressedSize + 1); int ChangedOffset = (int)ByteTools.Read4Bytes(ROM, (uint)BufOffset) - OffsetToChange; RomL.RemoveRange(BufOffset, 4); buf = BitConverter.GetBytes(ChangedOffset); if (BitConverter.IsLittleEndian) { Array.Reverse(buf); } RomL.InsertRange(BufOffset, buf); BufOffset += 8; } while (RomL.Count - 1 < 0x7FFFFF) { RomL.Add(0x00); } //trim ROM while ((RomL.Count - 1) % 0x400000 != 0x3FFFFF) { RomL.RemoveAt(RomL.Count - 1); } return(RomL.ToArray()); }