private static void MakeSfrom(ref byte[] rawRomData, ref byte saveCount) { var romHeaderLoRom = SnesRomHeader.Read(rawRomData, 0x7FC0); var romHeaderHiRom = SnesRomHeader.Read(rawRomData, 0xFFC0); SnesRomHeader romHeader; bool loRom = true; bool hiRom = true; if (romHeaderLoRom.GameTitle.Length == 0) { loRom = false; } foreach (char c in romHeaderLoRom.GameTitle) { if (c < 31 || c > 127) { loRom = false; } } if (romHeaderHiRom.GameTitle.Length == 0) { hiRom = false; } foreach (char c in romHeaderHiRom.GameTitle) { if (c < 31 || c > 127) { hiRom = false; } } SnesRomType romType; if (loRom && !hiRom) { romType = SnesRomType.LoRom; romHeader = romHeaderLoRom; } else if (!loRom && hiRom) { romType = SnesRomType.HiRom; romHeader = romHeaderHiRom; } else if (((romHeaderLoRom.RomMakeup & 1) == 0) && ((romHeaderHiRom.RomMakeup & 1) == 0)) { romType = SnesRomType.LoRom; romHeader = romHeaderLoRom; } else if (((romHeaderLoRom.RomMakeup & 1) == 1) && ((romHeaderHiRom.RomMakeup & 1) == 1)) { romType = SnesRomType.HiRom; romHeader = romHeaderHiRom; } else { // WTF is it? romType = SnesRomType.HiRom; romHeader = romHeaderHiRom; } string gameTitle = romHeader.GameTitle.Trim(); Debug.WriteLine($"Game title: {gameTitle}"); ushort presetId = 0; // 0x1011; ushort chip = 0; if (SfxTypes.Contains(romHeader.RomType)) // Super FX chip { Debug.WriteLine($"Super FX chip detected"); chip = 0x0C; } if (!knownPresets.TryGetValue(gameTitle, out presetId)) // Known codes { if (Dsp1Types.Contains(romHeader.RomType)) { Debug.WriteLine($"DSP-1 chip detected"); presetId = 0x10BD; // ID from Mario Kard, DSP1 } if (SA1Types.Contains(romHeader.RomType)) { Debug.WriteLine($"SA1 chip detected"); presetId = 0x109C; // ID from Super Mario RPG, SA1 } } Debug.WriteLine(string.Format("PresetID: 0x{0:X2}{1:X2}, extra byte: {2:X2}", presetId & 0xFF, (presetId >> 8) & 0xFF, chip)); var sfromHeader1 = new SfromHeader1((uint)rawRomData.Length); var sfromHeader2 = new SfromHeader2((uint)rawRomData.Length, presetId, romType, chip); var sfromHeader1Raw = sfromHeader1.GetBytes(); var sfromHeader2Raw = sfromHeader2.GetBytes(); var result = new byte[sfromHeader1Raw.Length + rawRomData.Length + sfromHeader2Raw.Length]; Array.Copy(sfromHeader1Raw, 0, result, 0, sfromHeader1Raw.Length); Array.Copy(rawRomData, 0, result, sfromHeader1Raw.Length, rawRomData.Length); Array.Copy(sfromHeader2Raw, 0, result, sfromHeader1Raw.Length + rawRomData.Length, sfromHeader2Raw.Length); if (romHeader.SramSize > 0) { saveCount = 3; } rawRomData = result; }
public static SnesRomHeader GetCorrectHeader(byte[] rawRomData, out SnesRomType romType, out string gameTitle) { var romHeaderLoRom = SnesRomHeader.Read(rawRomData, 0x7FC0); var romHeaderHiRom = SnesRomHeader.Read(rawRomData, 0xFFC0); var titleLo = romHeaderLoRom.GameTitle; var titleHi = romHeaderHiRom.GameTitle; // Boring LoRom/HiRom detection... if (((romHeaderLoRom.Checksum ^ 0xFFFF) == romHeaderLoRom.ChecksumComplement) && ((romHeaderHiRom.Checksum ^ 0xFFFF) != romHeaderHiRom.ChecksumComplement || romHeaderHiRom.Checksum == 0 || romHeaderHiRom.ChecksumComplement == 0)) { romType = SnesRomType.LoRom; } else if (((romHeaderLoRom.Checksum ^ 0xFFFF) != romHeaderLoRom.ChecksumComplement || romHeaderLoRom.Checksum == 0 || romHeaderLoRom.ChecksumComplement == 0) && ((romHeaderHiRom.Checksum ^ 0xFFFF) == romHeaderHiRom.ChecksumComplement)) { romType = SnesRomType.HiRom; } else if (titleLo.Length != 0 && titleHi.Length == 0) { romType = SnesRomType.LoRom; } else if (titleLo.Length == 0 && titleHi.Length != 0) { romType = SnesRomType.HiRom; } else if ((titleLo == titleHi) && ((romHeaderLoRom.RomMakeup & 1) == 0)) { romType = SnesRomType.LoRom; } else if ((titleLo == titleHi) && ((romHeaderHiRom.RomMakeup & 1) == 1)) { romType = SnesRomType.HiRom; } else if (gamesLoRom.Contains(titleLo)) { romType = SnesRomType.LoRom; } else if (gamesHiRom.Contains(titleHi)) { romType = SnesRomType.HiRom; } else { bool loRom = true; bool hiRom = true; foreach (char c in titleLo) { if (c < 31 || c > 127) { loRom = false; } } foreach (char c in titleHi) { if (c < 31 || c > 127) { hiRom = false; } } if (loRom && !hiRom) { romType = SnesRomType.LoRom; } else if (!loRom && hiRom) { romType = SnesRomType.HiRom; } else { Trace.WriteLine("Can't detect ROM type"); throw new Exception("can't detect ROM type, seems like ROM is corrupted"); } } SnesRomHeader romHeader; if (romType == SnesRomType.LoRom) { romHeader = romHeaderLoRom; gameTitle = titleLo; } else { romHeader = romHeaderHiRom; gameTitle = titleHi; } return(romHeader); }
private static void MakeSfrom(ref byte[] rawRomData) { var romHeaderLoRom = SnesRomHeader.Read(rawRomData, 0x7FC0); var romHeaderHiRom = SnesRomHeader.Read(rawRomData, 0xFFC0); SnesRomHeader romHeader; bool loRom = true; bool hiRom = true; if (romHeaderLoRom.GameTitle.Length == 0) { loRom = false; } foreach (char c in romHeaderLoRom.GameTitle) { if (c < 31 || c > 127) { loRom = false; } } if (romHeaderHiRom.GameTitle.Length == 0) { hiRom = false; } foreach (char c in romHeaderHiRom.GameTitle) { if (c < 31 || c > 127) { hiRom = false; } } SnesRomType romType; if (loRom && !hiRom) { romType = SnesRomType.LoRom; romHeader = romHeaderLoRom; } else if (!loRom && hiRom) { romType = SnesRomType.HiRom; romHeader = romHeaderHiRom; } else if ((romHeaderLoRom.RomMakeup & 1) == 0) { romType = SnesRomType.LoRom; romHeader = romHeaderLoRom; } else { romType = SnesRomType.HiRom; romHeader = romHeaderHiRom; } string gameTitle = romHeader.GameTitle.Trim(); ushort presetId = 0; // 0x1011; ushort chip = 0; if (SfxTypes.Contains(romHeader.RomType)) // Super FX chip { chip = 0x0C; } if (!knownPresets.TryGetValue(gameTitle, out presetId)) // Known codes { if (Dsp1Types.Contains(romHeader.RomType)) { presetId = 0x10BD; // ID from Mario Kard, DSP1 } if (SA1Types.Contains(romHeader.RomType)) { presetId = 0x109C; // ID from Super Mario RPG, SA1 } } var sfromHeader1 = new SfromHeader1((uint)rawRomData.Length); var sfromHeader2 = new SfromHeader2((uint)rawRomData.Length, presetId, romType, chip); var sfromHeader1Raw = sfromHeader1.GetBytes(); var sfromHeader2Raw = sfromHeader2.GetBytes(); var result = new byte[sfromHeader1Raw.Length + rawRomData.Length + sfromHeader2Raw.Length]; Array.Copy(sfromHeader1Raw, 0, result, 0, sfromHeader1Raw.Length); Array.Copy(rawRomData, 0, result, sfromHeader1Raw.Length, rawRomData.Length); Array.Copy(sfromHeader2Raw, 0, result, sfromHeader1Raw.Length + rawRomData.Length, sfromHeader2Raw.Length); rawRomData = result; }