Exemplo n.º 1
0
            public override string GetRomFormatName(byte[] rom)
            {
                var swapped = N64.IsByteswapped(rom);

                if (swapped == N64ByteSwap.NotSwapped)
                {
                    return("N64 ROM image");
                }
                if (swapped == N64ByteSwap.Swapped)
                {
                    return("N64 ROM image (byte-swapped)");
                }

                return("N64 ROM image (byte-swapping unknown)");
            }
        public mupen64plusApi(N64 bizhawkCore, byte[] rom, VideoPluginSettings video_settings, int SaveType, int CoreType, bool DisableExpansionSlot)
        {
            // There can only be one core (otherwise breaks mupen64plus)
            if (AttachedCore != null)
            {
                AttachedCore.Dispose();
                AttachedCore = null;
            }
            this.bizhawkCore = bizhawkCore;

            CoreDll = LoadLibrary("mupen64plus.dll");
            if (CoreDll == IntPtr.Zero)
            {
                throw new InvalidOperationException(string.Format("Failed to load mupen64plus.dll"));
            }

            connectFunctionPointers();

            // Start up the core
            m64p_error result = m64pCoreStartup(0x20001, "", "", "Core",
                                                null, "", IntPtr.Zero);

            // Open the core settings section in the config system
            IntPtr core_section = IntPtr.Zero;

            m64pConfigOpenSection("Core", ref core_section);

            // Set the savetype if needed
            if (DisableExpansionSlot)
            {
                int disable = 1;
                m64pConfigSetParameter(core_section, "DisableExtraMem", m64p_type.M64TYPE_INT, ref disable);
            }

            // Set the savetype if needed
            if (SaveType != 0)
            {
                m64pConfigSetParameter(core_section, "SaveType", m64p_type.M64TYPE_INT, ref SaveType);
            }

            m64pConfigSetParameter(core_section, "R4300Emulator", m64p_type.M64TYPE_INT, ref CoreType);

            // Pass the rom to the core
            result = m64pCoreDoCommandByteArray(m64p_command.M64CMD_ROM_OPEN, rom.Length, rom);

            // Open the general video settings section in the config system
            IntPtr video_section = IntPtr.Zero;

            m64pConfigOpenSection("Video-General", ref video_section);

            // Set the desired width and height for mupen64plus
            result = m64pConfigSetParameter(video_section, "ScreenWidth", m64p_type.M64TYPE_INT, ref video_settings.Width);
            result = m64pConfigSetParameter(video_section, "ScreenHeight", m64p_type.M64TYPE_INT, ref video_settings.Height);

            set_video_parameters(video_settings);

            InitSaveram();

            // Initialize event invoker
            m64pFrameCallback  = new FrameCallback(FireFrameFinishedEvent);
            result             = m64pCoreDoCommandFrameCallback(m64p_command.M64CMD_SET_FRAME_CALLBACK, 0, m64pFrameCallback);
            m64pVICallback     = new VICallback(FireVIEvent);
            result             = m64pCoreDoCommandVICallback(m64p_command.M64CMD_SET_VI_CALLBACK, 0, m64pVICallback);
            m64pRenderCallback = new RenderCallback(FireRenderEvent);
            result             = m64pCoreDoCommandRenderCallback(m64p_command.M64CMD_SET_RENDER_CALLBACK, 0, m64pRenderCallback);

            // Prepare to start the emulator in a different thread
            m64pEmulator = new Thread(ExecuteEmulator);

            AttachedCore = this;
        }
Exemplo n.º 3
0
		public mupen64plusApi(N64 bizhawkCore, byte[] rom, VideoPluginSettings video_settings, int SaveType, int CoreType, bool DisableExpansionSlot)
		{
			// There can only be one core (otherwise breaks mupen64plus)
			if (AttachedCore != null)
			{
				AttachedCore.Dispose();
				AttachedCore = null;
			}
			this.bizhawkCore = bizhawkCore;

			CoreDll = LoadLibrary("mupen64plus.dll");
			if (CoreDll == IntPtr.Zero)
				throw new InvalidOperationException(string.Format("Failed to load mupen64plus.dll"));

			connectFunctionPointers();

			// Start up the core
			m64p_error result = m64pCoreStartup(0x20001, "", "", "Core",
				null, "", IntPtr.Zero);

			// Set the savetype if needed
			if (DisableExpansionSlot)
			{
				IntPtr core_section = IntPtr.Zero;
				int disable = 1;
				m64pConfigOpenSection("Core", ref core_section);
				m64pConfigSetParameter(core_section, "DisableExtraMem", m64p_type.M64TYPE_INT, ref disable);
			}

			// Set the savetype if needed
			if (SaveType != 0)
			{
				IntPtr core_section = IntPtr.Zero;
				m64pConfigOpenSection("Core", ref core_section);
				m64pConfigSetParameter(core_section, "SaveType", m64p_type.M64TYPE_INT, ref SaveType);
			}

			IntPtr coreSection = IntPtr.Zero;
			m64pConfigOpenSection("Core", ref coreSection);
			m64pConfigSetParameter(coreSection, "R4300Emulator", m64p_type.M64TYPE_INT, ref CoreType);

			// Pass the rom to the core
			result = m64pCoreDoCommandByteArray(m64p_command.M64CMD_ROM_OPEN, rom.Length, rom);

			// Open the general video settings section in the config system
			IntPtr video_section = IntPtr.Zero;
			m64pConfigOpenSection("Video-General", ref video_section);

			// Set the desired width and height for mupen64plus
			result = m64pConfigSetParameter(video_section, "ScreenWidth", m64p_type.M64TYPE_INT, ref video_settings.Width);
			result = m64pConfigSetParameter(video_section, "ScreenHeight", m64p_type.M64TYPE_INT, ref video_settings.Height);

			set_video_parameters(video_settings);

			InitSaveram();

			// Initialize event invoker
			m64pFrameCallback = new FrameCallback(FireFrameFinishedEvent);
			result = m64pCoreDoCommandFrameCallback(m64p_command.M64CMD_SET_FRAME_CALLBACK, 0, m64pFrameCallback);
			m64pVICallback = new VICallback(FireVIEvent);
			result = m64pCoreDoCommandVICallback(m64p_command.M64CMD_SET_VI_CALLBACK, 0, m64pVICallback);
			m64pRenderCallback = new RenderCallback(FireRenderEvent);
			result = m64pCoreDoCommandRenderCallback(m64p_command.M64CMD_SET_RENDER_CALLBACK, 0, m64pRenderCallback);

			// Prepare to start the emulator in a different thread
			m64pEmulator = new Thread(ExecuteEmulator);

			AttachedCore = this;
		}
Exemplo n.º 4
0
            public override void CalculateHashes(byte[] rom, IHashWorkManager worker, float startProgress, float endProgress)
            {
                // N64 hashes are calculated using the thread pool because the ROMs tend to be large

                bool byteswapped = N64.IsByteswapped(rom) == N64ByteSwap.Swapped;

                byte[] swappedRom = new byte[rom.Length];
                // Watch out for odd # of bytes!
                int len = rom.Length & (~1);

                for (int i = 0; i < len; i += 2)
                {
                    swappedRom[i]     = rom[i + 1];
                    swappedRom[i + 1] = rom[i];
                }

                HashFlags originalType = byteswapped ? HashFlags.RomHash_ByteSwap : HashFlags.RomHash;
                HashFlags swappedType  = byteswapped ? HashFlags.RomHash : HashFlags.RomHash_ByteSwap;

                worker.QueueTask((SimpleDelegate) delegate {
                    if (!worker.AbortPending)
                    {
                        worker.AddHashes(rom, 0, rom.Length, () => worker.AbortPending, HashFlags.SHA256, originalType, HashFlags.FileHash);
                    }
                });
                worker.QueueTask((SimpleDelegate) delegate {
                    if (!worker.AbortPending)
                    {
                        worker.AddHashes(rom, 0, rom.Length, () => worker.AbortPending, HashFlags.SHA1, originalType, HashFlags.FileHash);
                    }
                });
                worker.QueueTask((SimpleDelegate) delegate {
                    if (!worker.AbortPending)
                    {
                        worker.AddHashes(rom, 0, rom.Length, () => worker.AbortPending, HashFlags.CRC32, originalType, HashFlags.FileHash);
                    }
                });
                worker.QueueTask((SimpleDelegate) delegate {
                    if (!worker.AbortPending)
                    {
                        worker.AddHashes(rom, 0, rom.Length, () => worker.AbortPending, HashFlags.MD5, originalType, HashFlags.FileHash);
                    }
                });

                // We can not byte-swap the ROM while it is being hashed
                worker.WaitAll();


                worker.QueueTask((SimpleDelegate) delegate {
                    if (!worker.AbortPending)
                    {
                        worker.AddHashes(swappedRom, 0, swappedRom.Length, () => worker.AbortPending, HashFlags.SHA256, swappedType);
                    }
                });
                worker.QueueTask((SimpleDelegate) delegate {
                    if (!worker.AbortPending)
                    {
                        worker.AddHashes(swappedRom, 0, swappedRom.Length, () => worker.AbortPending, HashFlags.SHA1, swappedType);
                    }
                });
                worker.QueueTask((SimpleDelegate) delegate {
                    if (!worker.AbortPending)
                    {
                        worker.AddHashes(swappedRom, 0, swappedRom.Length, () => worker.AbortPending, HashFlags.CRC32, swappedType);
                    }
                });
                worker.QueueTask((SimpleDelegate) delegate {
                    if (!worker.AbortPending)
                    {
                        worker.AddHashes(swappedRom, 0, swappedRom.Length, () => worker.AbortPending, HashFlags.MD5, swappedType);
                    }
                });

                // We can not return until all hashes are calculated
                worker.WaitAll();
            }
Exemplo n.º 5
0
 public override bool IsPlatformMatch(byte[] rom)
 {
     // Check for a valid normal or byteswapped header
     return(N64.IsByteswapped(rom) != N64ByteSwap.Unknown);
 }
Exemplo n.º 6
0
            internal override void InitRomData(RomData data, byte[] rom)
            {
                base.InitRomData(data, rom);

                data.MiscData.Add(ByteswapTagID, N64.IsByteswapped(rom));
            }
Exemplo n.º 7
0
 protected override void AddPlatformExtendedData(Platform.RomExDataBuilder builder, byte[] rom, RomData data)
 {
     builder.AddData(RomExDataBuilder.GeneralCat, "Byte-swapped", N64.IsByteswapped(rom).GetDescription());
 }
Exemplo n.º 8
0
        public bool LoadRom(string path, CoreComm nextComm, bool forceAccurateCore = false)         // forceAccurateCore is currently just for Quicknes vs Neshawk but could be used for other situations
        {
            if (path == null)
            {
                return(false);
            }

            using (var file = new HawkFile())
            {
                var romExtensions = new[] { "SMS", "SMC", "SFC", "PCE", "SGX", "GG", "SG", "BIN", "GEN", "MD", "SMD", "GB", "NES", "FDS", "ROM", "INT", "GBC", "UNF", "A78", "CRT", "COL", "XML", "Z64", "V64", "N64", "WS", "WSC" };

                // lets not use this unless we need to
                // file.NonArchiveExtensions = romExtensions;
                file.Open(path);

                // if the provided file doesnt even exist, give up!
                if (!file.Exists)
                {
                    return(false);
                }

                // try binding normal rom extensions first
                if (!file.IsBound)
                {
                    file.BindSoleItemOf(romExtensions);
                }

                // if we have an archive and need to bind something, then pop the dialog
                if (file.IsArchive && !file.IsBound)
                {
                    var result = HandleArchive(file);
                    if (result.HasValue)
                    {
                        file.BindArchiveMember(result.Value);
                    }
                    else
                    {
                        return(false);
                    }
                }

                // set this here so we can see what file we tried to load even if an error occurs
                CanonicalFullPath = file.CanonicalFullPath;

                IEmulator nextEmulator = null;
                RomGame   rom          = null;
                GameInfo  game         = null;

                try
                {
                    var ext = file.Extension.ToLower();
                    if (ext == ".iso" || ext == ".cue")
                    {
                        var disc = ext == ".iso" ? Disc.FromIsoPath(path) : Disc.FromCuePath(path, new CueBinPrefs());
                        var hash = disc.GetHash();
                        game = Database.CheckDatabase(hash);
                        if (game == null)
                        {
                            // try to use our wizard methods
                            game = new GameInfo {
                                Name = Path.GetFileNameWithoutExtension(file.Name), Hash = hash
                            };

                            switch (disc.DetectDiscType())
                            {
                            case DiscType.SegaSaturn:
                                game.System = "SAT";
                                break;

                            case DiscType.SonyPSP:
                                game.System = "PSP";
                                break;

                            case DiscType.SonyPSX:
                                game.System = "PSX";
                                break;

                            case DiscType.MegaCD:
                                game.System = "GEN";
                                break;

                            case DiscType.TurboCD:
                            case DiscType.UnknownCDFS:
                            case DiscType.UnknownFormat:
                            default:                                     // PCECD was bizhawk's first CD core,
                                // and during that time, all CDs were blindly sent to it
                                // so this prevents regressions
                                game.System = "PCECD";
                                break;
                            }
                        }

                        switch (game.System)
                        {
                        case "GEN":
                            var genesis = new GPGX(
                                nextComm, null, disc, "GEN", GetCoreSettings <GPGX>(), GetCoreSyncSettings <GPGX>());
                            nextEmulator = genesis;
                            break;

                        case "SAT":
                            nextEmulator = new Yabause(nextComm, disc, GetCoreSyncSettings <Yabause>());
                            break;

                        case "PSP":
                            nextEmulator = new PSP(nextComm, file.Name);
                            break;

                        case "PSX":
                            nextEmulator = new Octoshock(nextComm);
                            (nextEmulator as Octoshock).LoadCuePath(file.CanonicalFullPath);
                            nextEmulator.CoreComm.RomStatusDetails = "PSX etc.";
                            break;

                        case "PCE":
                        case "PCECD":
                            nextEmulator = new PCEngine(nextComm, game, disc, GetCoreSettings <PCEngine>(), GetCoreSyncSettings <PCEngine>());
                            break;
                        }
                    }
                    else if (file.Extension.ToLower() == ".xml")
                    {
                        try
                        {
                            var xmlGame = XmlGame.Create(file);                             // if load fails, are we supposed to retry as a bsnes XML????????
                            game = xmlGame.GI;

                            switch (game.System)
                            {
                            case "DGB":
                                var left  = Database.GetGameInfo(xmlGame.Assets["LeftRom"], "left.gb");
                                var right = Database.GetGameInfo(xmlGame.Assets["RightRom"], "right.gb");
                                nextEmulator = new GambatteLink(
                                    nextComm,
                                    left,
                                    xmlGame.Assets["LeftRom"],
                                    right,
                                    xmlGame.Assets["RightRom"],
                                    GetCoreSettings <GambatteLink>(),
                                    GetCoreSyncSettings <GambatteLink>(),
                                    Deterministic);

                                // other stuff todo
                                break;

                            default:
                                return(false);
                            }
                        }
                        catch (Exception ex)
                        {
                            DoLoadErrorCallback(ex.ToString(), "DGB", LoadErrorType.XML);
                            return(false);
                        }
                    }
                    else                     // most extensions
                    {
                        rom = new RomGame(file);

                        if (string.IsNullOrEmpty(rom.GameInfo.System))
                        {
                            // Has the user picked a preference for this extension?
                            if (PreferredPlatformIsDefined(rom.Extension.ToLower()))
                            {
                                rom.GameInfo.System = Global.Config.PreferredPlatformsForExtensions[rom.Extension.ToLower()];
                            }
                            else if (ChoosePlatform != null)
                            {
                                rom.GameInfo.System = ChoosePlatform(rom);
                            }
                        }

                        game = rom.GameInfo;

                        var isXml = false;

                        // other xml has already been handled
                        if (file.Extension.ToLower() == ".xml")
                        {
                            game.System = "SNES";
                            isXml       = true;
                        }

                        switch (game.System)
                        {
                        case "SNES":
                            if (Global.Config.SNES_InSnes9x && VersionInfo.DeveloperBuild)
                            {
                                var snes = new Emulation.Cores.Nintendo.SNES9X.Snes9x(nextComm, rom.FileData);
                                nextEmulator = snes;
                            }
                            else
                            {
                                // need to get rid of this hack at some point
                                ((CoreFileProvider)nextComm.CoreFileProvider).SubfileDirectory = Path.GetDirectoryName(path.Replace("|", String.Empty));                                         // Dirty hack to get around archive filenames (since we are just getting the directory path, it is safe to mangle the filename
                                var romData = isXml ? null : rom.FileData;
                                var xmlData = isXml ? rom.FileData : null;
                                var snes    = new LibsnesCore(game, romData, Deterministic, xmlData, nextComm, GetCoreSettings <LibsnesCore>(), GetCoreSyncSettings <LibsnesCore>());
                                nextEmulator = snes;
                            }

                            RACore.OnLoad(RAConsoleID.SNES, rom.GameInfo.Name, rom.GameInfo.Hash);

                            break;

                        case "SMS":
                        case "SG":
                        case "GG":
                            nextEmulator = new SMS(nextComm, game, rom.RomData, GetCoreSettings <SMS>(), GetCoreSyncSettings <SMS>());
                            RACore.OnLoad(RAConsoleID.MasterSystem, rom.GameInfo.Name, rom.GameInfo.Hash);
                            break;

                        case "A26":
                            nextEmulator = new Atari2600(
                                nextComm,
                                game,
                                rom.FileData,
                                GetCoreSettings <Atari2600>(),
                                GetCoreSyncSettings <Atari2600>());
                            break;

                        case "PCE":
                        case "PCECD":
                        case "SGX":
                            nextEmulator = new PCEngine(nextComm, game, rom.RomData, GetCoreSettings <PCEngine>(), GetCoreSyncSettings <PCEngine>());
                            RACore.OnLoad(RAConsoleID.PCEngine, rom.GameInfo.Name, rom.GameInfo.Hash);
                            break;

                        case "GEN":
                            nextEmulator = new GPGX(nextComm, rom.RomData, null, "GEN", GetCoreSettings <GPGX>(), GetCoreSyncSettings <GPGX>());
                            RACore.OnLoad(RAConsoleID.MegaDrive, rom.GameInfo.Name, rom.GameInfo.Hash);
                            break;

                        case "TI83":
                            nextEmulator = new TI83(nextComm, game, rom.RomData, GetCoreSettings <TI83>());
                            break;

                        case "NES":
                            if (!Global.Config.NES_InQuickNES || forceAccurateCore)
                            {
                                nextEmulator = new NES(
                                    nextComm,
                                    game,
                                    rom.FileData,
                                    GetCoreSettings <NES>(),
                                    GetCoreSyncSettings <NES>());
                            }
                            else
                            {
                                nextEmulator = new QuickNES(nextComm, rom.FileData, GetCoreSettings <QuickNES>());
                            }

                            RACore.OnLoad(RAConsoleID.NES, rom.GameInfo.Name, rom.GameInfo.Hash);
                            break;

                        case "GB":
                        case "GBC":
                            if (!Global.Config.GB_AsSGB)
                            {
                                nextEmulator = new Gameboy(
                                    nextComm,
                                    game,
                                    rom.FileData,
                                    GetCoreSettings <Gameboy>(),
                                    GetCoreSyncSettings <Gameboy>(),
                                    Deterministic);
                            }
                            else
                            {
                                try
                                {
                                    game.System = "SNES";
                                    game.AddOption("SGB");
                                    var snes = new LibsnesCore(game, rom.FileData, Deterministic, null, nextComm, GetCoreSettings <LibsnesCore>(), GetCoreSyncSettings <LibsnesCore>());
                                    nextEmulator = snes;
                                }
                                catch
                                {
                                    // failed to load SGB bios or game does not support SGB mode.
                                    // To avoid catch-22, disable SGB mode
                                    Global.Config.GB_AsSGB = false;
                                    throw;
                                }
                            }

                            if (game.System == "GB")
                            {
                                RACore.OnLoad(RAConsoleID.Gameboy, rom.GameInfo.Name, rom.GameInfo.Hash);
                            }
                            else if (game.System == "GBC")
                            {
                                RACore.OnLoad(RAConsoleID.GameboyColor, rom.GameInfo.Name, rom.GameInfo.Hash);
                            }

                            break;

                        case "Coleco":
                            nextEmulator = new ColecoVision(nextComm, game, rom.RomData, GetCoreSyncSettings <ColecoVision>());
                            break;

                        case "INTV":
                            nextEmulator = new Intellivision(nextComm, game, rom.RomData);
                            break;

                        case "A78":
                            var gamedbpath = Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "EMU7800.csv");
                            nextEmulator = new Atari7800(nextComm, game, rom.RomData, gamedbpath);
                            break;

                        case "C64":
                            var c64 = new C64(nextComm, game, rom.RomData, rom.Extension);
                            nextEmulator = c64;
                            break;

                        case "GBA":
                            if (false)
                            {
                                //var gba = new GBA(nextComm);
                                //gba.Load(rom.RomData);
                                //nextEmulator = gba;
                            }
                            else
                            {
                                var gba = new VBANext(rom.RomData, nextComm);
                                nextEmulator = gba;

                                RACore.OnLoad(RAConsoleID.GameboyAdvance, rom.GameInfo.Name, rom.GameInfo.Hash);
                            }
                            break;

                        case "N64":
                            nextEmulator = new N64(nextComm, game, rom.RomData, GetCoreSettings <N64>(), GetCoreSyncSettings <N64>());
                            RACore.OnLoad(RAConsoleID.Nintendo64, rom.GameInfo.Name, rom.GameInfo.Hash);
                            break;

                        case "WSWAN":
                            nextEmulator = new WonderSwan(nextComm, rom.RomData, Deterministic,
                                                          GetCoreSettings <WonderSwan>(), GetCoreSyncSettings <WonderSwan>());
                            break;

                        case "DEBUG":
                            if (VersionInfo.DeveloperBuild)
                            {
                                nextEmulator = LibRetroEmulator.CreateDebug(nextComm, rom.RomData);
                            }

                            break;
                        }
                    }

                    if (nextEmulator == null)
                    {
                        DoLoadErrorCallback("No core could load the rom.", null);
                        return(false);
                    }
                }
                catch (Exception ex)
                {
                    string system = null;
                    if (game != null)
                    {
                        system = game.System;
                    }

                    // Specific hack here, as we get more cores of the same system, this isn't scalable
                    if (ex is UnsupportedMapperException)
                    {
                        return(LoadRom(path, nextComm, forceAccurateCore: true));
                    }
                    else if (ex is MissingFirmwareException)
                    {
                        DoLoadErrorCallback(ex.Message, system, LoadErrorType.MissingFirmware);
                    }
                    else if (ex is CGBNotSupportedException)
                    {
                        // Note: GB as SGB was set to false by this point, otherwise we would want to do it here
                        DoMessageCallback("Failed to load a GB rom in SGB mode.  Disabling SGB Mode.");
                        return(LoadRom(path, nextComm));
                    }
                    else
                    {
                        DoLoadErrorCallback("A core accepted the rom, but threw an exception while loading it:\n\n" + ex, system);
                    }

                    return(false);
                }

                Rom            = rom;
                LoadedEmulator = nextEmulator;
                Game           = game;
                return(true);
            }
        }