Ejemplo n.º 1
0
        /// <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());
        }