コード例 #1
0
ファイル: UPSUtil.cs プロジェクト: MrMeow76/FEBuilderGBA
        public static bool ApplyUPS(ROM retrom, string upsfilename)
        {
            byte[] patch = File.ReadAllBytes(upsfilename);
            if (patch.Length < 16)
            {
                R.ShowStopError("UPSファイルが壊れています。最低サイズ以下です。");
                return(false);
            }

            if (patch[0] != 'U' ||
                patch[1] != 'P' ||
                patch[2] != 'S' ||
                patch[3] != '1')
            {
                R.ShowStopError("UPSファイルが壊れています。ヘッダUPS1がありません。");
                return(false);
            }

            U.CRC32 crc32 = new U.CRC32();
            {
                uint patch_calc_crc32 = crc32.Calc(U.subrange(patch, 0, (uint)(patch.Length - 4)));
                uint patch_crc32      = U.u32(patch, (uint)(patch.Length - 4));
                if (patch_calc_crc32 != patch_crc32)
                {
                    R.ShowStopError("UPSファイルが壊れています。CRCが一致しません。");
                    return(false);
                }
            }
            {
                uint src_calc_crc32 = crc32.Calc(retrom.Data);
                uint src_crc32      = U.u32(patch, (uint)(patch.Length - 12));
                if (src_calc_crc32 != src_crc32)
                {
                    R.ShowStopError("現在開いているROMには適応できません。CRCが一致しません。");
                    return(false);
                }
            }

            uint i           = 4; //skip UPS1 header
            uint source_size = read_val_code(patch, i, out i);
            uint dest_size   = read_val_code(patch, i, out i);

            //無改造ROMのデータ
            byte[] bin = new byte[dest_size];
            Array.Copy(retrom.Data, 0, bin, 0, Math.Min(retrom.Data.Length, dest_size));

            uint romi = 0;
            uint end  = (uint)(patch.Length - 4 * 3);

            for (; i < end; i++)
            {
                uint skip_size = read_val_code(patch, i, out i);
                romi += skip_size;
                for (; i < end; i++)
                {
                    if (romi >= dest_size)
                    {
                        break;
                    }

                    bin[romi] = (byte)(bin[romi] ^ patch[i]);
                    romi++;
                    if (patch[i] == 0x00)
                    {
                        break;
                    }
                }
            }

            uint dest_calc_crc32 = crc32.Calc(bin);
            uint dest_crc32      = U.u32(patch, (uint)(patch.Length - 8));

            if (dest_calc_crc32 != dest_crc32)
            {
                R.ShowStopError("UPSを適応した結果が正しくありません。CRCが不一致です。");
                return(false);
            }

            retrom.SwapNewROMDataDirect(bin);
            retrom.ClearModifiedFlag();
            return(true);
        }