Ejemplo n.º 1
0
        private static void MakeSfrom(ref byte[] rawRomData, ref byte saveCount, out bool problemGame)
        {
            SnesRomType   romType;
            string        gameTitle;
            SnesRomHeader romHeader = GetCorrectHeader(rawRomData, out romType, out gameTitle);

            /*
             * if (romType == SnesRomType.LoRom)
             *  rawRomData[0x7FD9] = 0x01; // Force NTSC
             * else
             *  rawRomData[0xFFD9] = 0x01; // Force NTSC
             */

            Trace.WriteLine($"Game title: {gameTitle}");
            Trace.WriteLine($"ROM type: {romType}");
            ushort presetId = 0;
            byte   chip     = 0;

            if (SfxTypes.Contains(romHeader.RomType)) // Super FX chip
            {
                Trace.WriteLine($"Super FX chip detected");
                chip = 0x0C;
            }
            if (!knownPresets.TryGetValue(gameTitle, out presetId)) // Known codes
            {
                if (Dsp1Types.Contains(romHeader.RomType))
                {
                    Trace.WriteLine($"DSP-1 chip detected");
                    presetId = 0x10BD; // ID from Mario Kard, DSP1
                }
                if (SA1Types.Contains(romHeader.RomType))
                {
                    Trace.WriteLine($"SA1 chip detected");
                    presetId = 0x109C; // ID from Super Mario RPG, SA1
                }
            }
            else
            {
                Trace.WriteLine($"We have preset for this game");
            }
            Trace.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;
            }
            else
            {
                saveCount = 0;
            }

            problemGame = problemGames.Contains(gameTitle);

            rawRomData = result;
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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;
        }
Ejemplo n.º 4
0
        public static bool Patch(string inputFileName, ref byte[] rawRomData, ref char prefix, ref string application, ref string outputFileName, ref string args, ref Image cover, ref byte saveCount, ref uint crc32)
        {
            var ext = Path.GetExtension(inputFileName);

            if (inputFileName.Contains("(E)") || inputFileName.Contains("(J)"))
            {
                cover = Resources.blank_snes_eu_jp;
            }

            // already in sfrom?
            if (ext.ToLower() == ".sfrom")
            {
                Trace.WriteLine("ROM is already in SFROM format, no conversion needed");
                application = "/bin/clover-canoe-shvc-wr -rom";
                args        = DefaultCanoeArgs;
                return(true);
            }

            // header removal
            if ((ext.ToLower() == ".smc") && ((rawRomData.Length % 1024) != 0))
            {
                Trace.WriteLine("Removing SMC header");
                var stripped = new byte[rawRomData.Length - 512];
                Array.Copy(rawRomData, 512, stripped, 0, stripped.Length);
                rawRomData = stripped;
                crc32      = Shared.CRC32(rawRomData);
            }

            // check if we can use sfrom tool
            if (ConfigIni.Instance.ConvertToSFROM)
            {
                bool convertedSuccessfully = false;
                if (ConfigIni.Instance.UseSFROMTool && SfromToolWrapper.IsInstalled)
                {
                    try
                    {
                        SnesRomType   romType;
                        string        gameTitle;
                        SnesRomHeader romHeader = GetCorrectHeader(rawRomData, out romType, out gameTitle);
                        if (romHeader.SramSize > 0)
                        {
                            saveCount = 3;
                        }
                        else
                        {
                            saveCount = 0;
                        }
                    }
                    catch (Exception ex)
                    {
                        Trace.WriteLine("Error reading ROM header: " + ex.Message + ex.StackTrace);
                    }

                    Trace.WriteLine($"Convert with SFROM Tool: {inputFileName}");
                    if (SfromToolWrapper.ConvertROMtoSFROM(ref rawRomData))
                    {
                        outputFileName        = Path.GetFileNameWithoutExtension(outputFileName) + ".sfrom";
                        application           = "/bin/clover-canoe-shvc-wr -rom";
                        args                  = DefaultCanoeArgs;
                        convertedSuccessfully = true;
                    }
                    else
                    {
                        Trace.WriteLine("SFROM Tool conversion failed, attempting the built-in SFROM conversion");
                        convertedSuccessfully = false;
                    }
                }

                if (!convertedSuccessfully)
                {
                    // fallback method, with patching
                    FindPatch(ref rawRomData, inputFileName, crc32);

                    if (ConfigIni.Instance.ConvertToSFROM)
                    {
                        Trace.WriteLine($"Trying to convert {inputFileName}");
                        bool problemGame = false;
                        try
                        {
                            MakeSfrom(ref rawRomData, ref saveCount, out problemGame);
                        }
                        catch (Exception ex)
                        {
                            Tasks.ErrorForm.Show(MainForm.StaticRef, Resources.ImportGames, string.Format(Resources.ErrorImportingGame, Path.GetFileName(inputFileName)), ex.Message + ex.StackTrace, Resources.sign_error);
                            return(false);
                        }

                        // Using 3rd party emulator for this ROM?
                        outputFileName = Path.GetFileNameWithoutExtension(outputFileName) + ".sfrom";
                        if (problemGame && Need3rdPartyEmulator != true)
                        {
                            if (Need3rdPartyEmulator != false)
                            {
                                var result = Tasks.MessageForm.Show(ParentForm, Resources.AreYouSure,
                                                                    string.Format(Resources.Need3rdPartyEmulator, Path.GetFileName(inputFileName)),
                                                                    Resources.sign_warning,
                                                                    new Tasks.MessageForm.Button[] { Tasks.MessageForm.Button.YesToAll, Tasks.MessageForm.Button.Yes, Tasks.MessageForm.Button.No },
                                                                    Tasks.MessageForm.DefaultButton.Button2);
                                if (result == Tasks.MessageForm.Button.YesToAll)
                                {
                                    Need3rdPartyEmulator = true;
                                }
                                if (result == Tasks.MessageForm.Button.No)
                                {
                                    problemGame = false;
                                }
                            }
                            else
                            {
                                problemGame = false;
                            }
                        }
                        if (!problemGame)
                        {
                            application = "/bin/clover-canoe-shvc-wr -rom";
                            args        = DefaultCanoeArgs;
                        }
                    }
                }
            }

            return(true);
        }
Ejemplo n.º 5
0
        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;
        }