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); }