private static Subformat GetFormat(byte[] header) { Subformat format = Subformat.Indeterminate; if (header[0] == 0x80 && header[1] == 0x37 && header[2] == 0x12 && header[3] == 0x40) { format = Subformat.BigEndian; } else if (header[0] == 0x37 && header[1] == 0x80 && header[2] == 0x40 && header[3] == 0x12) { format = Subformat.ByteSwapped; } else if (header[0] == 0x40 && header[1] == 0x12 && header[2] == 0x37 && header[3] == 0x80) { format = Subformat.LittleEndian; } return(format); }
public RomNES(string filename) : base() { Header = Subformat.Indeterminate; byte[] header = new byte[0x10]; FileStream fs = File.OpenRead(filename); fs.Read(header, 0, 0x10); fs.Close(); Header = GetFormat(header); if (Header != Subformat.Indeterminate) { fs = File.Open(filename, FileMode.Open); Size = (int)fs.Length - (Header == Subformat.FDS ? 0 : 16); HashCRC16 = Cll.Security.ComputeCRC16(fs); fs.Close(); IsValid = true; Console = Format.NES; } else { throw new FormatException("It was not possible to determine the NES ROM format."); } }
public static void ToBigEndian(string source, string destination) { byte[] header = new byte[0x40]; FileStream fs = File.OpenRead(source); int size = (int)fs.Length; fs.Read(header, 0, 0x40); fs.Close(); Subformat format = GetFormat(header); if (format == Subformat.BigEndian || (format != Subformat.Indeterminate && size % 4 == 0)) { fs = File.OpenRead(source); byte[] data = new byte[fs.Length]; fs.Read(data, 0, data.Length); fs.Close(); data = ToBigEndian(data, format); fs = File.Open(destination, FileMode.Create); fs.Write(data, 0, data.Length); fs.Close(); } else { throw new Exception("The source file is not an N64 ROM."); } }
public static bool Validate(string filename) { if (File.Exists(filename)) { byte[] header = new byte[0x10]; FileStream fs = File.OpenRead(filename); fs.Read(header, 0, 0x10); fs.Close(); Subformat format = GetFormat(header); return(format != Subformat.Indeterminate); } return(false); }
public static bool Validate(string filename) { if (File.Exists(filename)) { FileStream fs = File.OpenRead(filename); int smcHeaderSize = SMCHeaderSize((int)fs.Length); byte[] data = GetData(fs, smcHeaderSize); fs.Close(); int headerOffset = -1; Subformat format = GetFormat(data, ref headerOffset); return(format != Subformat.Indeterminate); } return(false); }
public static bool Validate(string filename) { if (File.Exists(filename)) { byte[] header = new byte[0x40]; FileStream fs = File.OpenRead(filename); int size = (int)fs.Length; fs.Read(header, 0, 0x40); fs.Close(); Subformat format = GetFormat(header); return(format == Subformat.BigEndian || (format != Subformat.Indeterminate && size % 4 == 0)); } return(false); }
private static byte[] ToBigEndian(byte[] array, Subformat endianness) { if (array.Length % 4 != 0) { throw new Exception("ToBigEndian: Invalid array length."); } byte[] bigEndian = new byte[4]; if (endianness == Subformat.ByteSwapped) { for (int i = 0; i < array.Length / 4; i++) { bigEndian[0] = array[(i * 4) + 1]; bigEndian[1] = array[(i * 4) + 0]; bigEndian[2] = array[(i * 4) + 3]; bigEndian[3] = array[(i * 4) + 2]; array[(i * 4) + 0] = bigEndian[0]; array[(i * 4) + 1] = bigEndian[1]; array[(i * 4) + 2] = bigEndian[2]; array[(i * 4) + 3] = bigEndian[3]; } } else if (endianness == Subformat.LittleEndian) { for (int i = 0; i < array.Length / 4; i++) { bigEndian[0] = array[(i * 4) + 3]; bigEndian[1] = array[(i * 4) + 2]; bigEndian[2] = array[(i * 4) + 1]; bigEndian[3] = array[(i * 4) + 0]; array[(i * 4) + 0] = bigEndian[0]; array[(i * 4) + 1] = bigEndian[1]; array[(i * 4) + 2] = bigEndian[2]; array[(i * 4) + 3] = bigEndian[3]; } } return(array); }
private static byte[] ToBigEndian(byte[] array, Subformat endianness) { byte[] bigEndian = new byte[4]; if (endianness == Subformat.ByteSwapped) { for (int i = 0; i < array.Length / 4; i++) { bigEndian[0] = array[(i * 4) + 1]; bigEndian[1] = array[(i * 4) + 0]; bigEndian[2] = array[(i * 4) + 3]; bigEndian[3] = array[(i * 4) + 2]; array[(i * 4) + 0] = bigEndian[0]; array[(i * 4) + 1] = bigEndian[1]; array[(i * 4) + 2] = bigEndian[2]; array[(i * 4) + 3] = bigEndian[3]; } } else if (endianness == Subformat.LittleEndian) { for (int i = 0; i < array.Length / 4; i++) { bigEndian[0] = array[(i * 4) + 3]; bigEndian[1] = array[(i * 4) + 2]; bigEndian[2] = array[(i * 4) + 1]; bigEndian[3] = array[(i * 4) + 0]; array[(i * 4) + 0] = bigEndian[0]; array[(i * 4) + 1] = bigEndian[1]; array[(i * 4) + 2] = bigEndian[2]; array[(i * 4) + 3] = bigEndian[3]; } } return(array); }
private static Subformat GetFormat(byte[] header) { Subformat format = Subformat.Indeterminate; if (header[0] == 0x4E && header[1] == 0x45 && header[2] == 0x53 && header[3] == 0x1A) { if ((header[7] & 0x0C) == 0x08) { format = Subformat.NES20; } else { format = Subformat.iNES; } } else if (header[0] == 0x01 && header[1] == 0x2A && header[2] == 0x4E && header[3] == 0x49 && header[4] == 0x4E && header[5] == 0x54 && header[6] == 0x45 && header[7] == 0x4E && header[8] == 0x44 && header[9] == 0x4F && header[10] == 0x2D && header[11] == 0x48 && header[12] == 0x56 && header[13] == 0x43 && header[14] == 0x2A) { format = Subformat.FDS; } return(format); }
public RomSNES(string filename) : base() { IsSMC = false; Mode = Subformat.Indeterminate; FileStream fs = File.OpenRead(filename); int smcHeaderSize = SMCHeaderSize((int)fs.Length); byte[] data = GetData(fs, smcHeaderSize); fs.Close(); if (smcHeaderSize == 0x200) { IsSMC = true; } int headerOffset = -1; Mode = GetFormat(data, ref headerOffset); if (Mode != Subformat.Indeterminate) { if (data[headerOffset + 0x2A] == 0x33) { byte uniqueCode; byte[] shortTitle = new byte[2]; byte region; uniqueCode = data[headerOffset + 0x02]; shortTitle[0] = data[headerOffset + 0x03]; shortTitle[1] = data[headerOffset + 0x04]; region = data[headerOffset + 0x05]; if (Useful.IsUpperLetterOrDigit(uniqueCode)) { FormatCode = (char)uniqueCode; } if (Useful.IsUpperLetterOrDigit(shortTitle[0]) && Useful.IsUpperLetterOrDigit(shortTitle[1])) { ShortId = Encoding.ASCII.GetString(shortTitle); } if (Useful.IsUpperLetterOrDigit(region)) { RegionCode = (char)region; } } Version = data[headerOffset + 0x2B]; byte[] titleBytes = new byte[21]; Array.Copy(data, headerOffset + 0x10, titleBytes, 0, 21); int count = 21; while (--count >= 0 && titleBytes[count] == 0x20) { ; } Title = Encoding.ASCII.GetString(titleBytes, 0, count + 1); Size = data.Length; HashCRC16 = Cll.Security.ComputeCRC16_ARC(data, 0, data.Length); IsValid = true; Console = Format.SNES_USA; } else { Size = 0; throw new FormatException("It was not possible to determine the SNES ROM format."); } }
private static Subformat GetFormat(byte[] data, ref int headerOffset) { Subformat format = Subformat.Indeterminate; if (data != null) { ushort checksum16 = Cll.Security.Checksum16(data, 0, data.Length); ushort checksumCL = (ushort)(data[0x7FDC] + (data[0x7FDD] << 8)); ushort checksumL = (ushort)(data[0x7FDE] + (data[0x7FDF] << 8)); ushort checksumCH = (ushort)(data[0xFFDC] + (data[0xFFDD] << 8)); ushort checksumH = (ushort)(data[0xFFDE] + (data[0xFFDF] << 8)); if ((checksumCL ^ 0xFFFF) == checksumL && checksumL == checksum16) { format = Subformat.LoROM; headerOffset = 0x7FB0; } else if ((checksumCH ^ 0xFFFF) == checksumH && checksumH == checksum16) { format = Subformat.HiROM; headerOffset = 0xFFB0; } else { headerOffset = 0x7FB0; format = Subformat.LoROM; for (int i = 0; i < 21; i++) { if (data[headerOffset + 0x10 + i] < 0x20 || data[headerOffset + 0x10 + i] > 0x7E) { headerOffset = 0xFFB0; break; } } if (headerOffset == 0xFFB0) { format = Subformat.HiROM; for (int i = 0; i < 21; i++) { if (data[headerOffset + 0x10 + i] < 0x20 || data[headerOffset + 0x10 + i] > 0x7E) { headerOffset = -1; format = Subformat.Indeterminate; break; } } } if ( format != Subformat.Indeterminate && ( (data[headerOffset + 0x27] > 0x0D || data[headerOffset + 0x28] > 0x08) || (Math.Pow(2.0, 3.0 + data[headerOffset + 0x27]) / 8.0 > data.Length) || (data[headerOffset + 0x25] != 0x20 && //Slow + LoROM data[headerOffset + 0x25] != 0x21 && //Slow + HiROM data[headerOffset + 0x25] != 0x22 && //Slow + LoROM (S-DD1) [?] data[headerOffset + 0x25] != 0x23 && //Slow + LoROM (SA-1) data[headerOffset + 0x25] != 0x25 && //Slow + ExHiROM [?] data[headerOffset + 0x25] != 0x2A && //Slow + ExHiROM (SPC7110) [?] data[headerOffset + 0x25] != 0x30 && //Fast + LoROM data[headerOffset + 0x25] != 0x31 && //Fast + HiROM data[headerOffset + 0x25] != 0x32 && //Fast + ExLoROM (or LoROM (S-DD1) [?]) data[headerOffset + 0x25] != 0x33 && //Fast + LoROM (SA-1) [?] data[headerOffset + 0x25] != 0x35 && //Fast + ExHiROM data[headerOffset + 0x25] != 0x3A) //Fast + ExHiROM (SPC7110) ) ) { format = Subformat.Indeterminate; } } } return(format); }
public RomN64(string filename) : base() { Endianness = Subformat.Indeterminate; byte[] header = new byte[0x40]; FileStream fs = File.Open(filename, FileMode.Open); Size = (int)fs.Length; fs.Read(header, 0, 0x40); fs.Close(); Endianness = GetFormat(header); if (Endianness == Subformat.BigEndian || (Endianness != Subformat.Indeterminate && Size % 4 == 0)) { byte uniqueCode; byte[] shortTitle = new byte[2]; byte region; header = ToBigEndian(header, Endianness); uniqueCode = header[0x3B]; shortTitle[0] = header[0x3C]; shortTitle[1] = header[0x3D]; region = header[0x3E]; if (Useful.IsUpperLetterOrDigit(uniqueCode)) { FormatCode = (char)uniqueCode; } if (Useful.IsUpperLetterOrDigit(shortTitle[0]) && Useful.IsUpperLetterOrDigit(shortTitle[1])) { ShortId = Encoding.ASCII.GetString(shortTitle); } if (Useful.IsUpperLetterOrDigit(region)) { RegionCode = (char)region; } if (Useful.IsUpperLetterOrDigit(header[0x3F])) { Version = header[0x3F]; } byte[] titleBytes = new byte[20]; Array.Copy(header, 0x20, titleBytes, 0, 20); int count = 20; while (--count >= 0 && titleBytes[count] == 0x20) { ; } Title = Encoding.ASCII.GetString(titleBytes, 0, count + 1); fs = File.Open(filename, FileMode.Open); HashCRC16 = Cll.Security.ComputeCRC16(fs); fs.Close(); IsValid = true; Console = Format.N64; } else { Size = 0; throw new FormatException("It was not possible to determine the N64 ROM format."); } }