예제 #1
0
		public LibsnesCore(GameInfo game, byte[] romData, bool deterministicEmulation, byte[] xmlData, CoreComm comm, object Settings, object SyncSettings)
		{
			CoreComm = comm;
			byte[] sgbRomData = null;
			if (game["SGB"])
			{
				if ((romData[0x143] & 0xc0) == 0xc0)
					throw new CGBNotSupportedException();
				sgbRomData = CoreComm.CoreFileProvider.GetFirmware("SNES", "Rom_SGB", true, "SGB Rom is required for SGB emulation.");
				game.FirmwareHash = sgbRomData.HashSHA1();
			}

			this.Settings = (SnesSettings)Settings ?? new SnesSettings();
			this.SyncSettings = (SnesSyncSettings)SyncSettings ?? new SnesSyncSettings();

			api = new LibsnesApi(GetExePath());
			api.CMD_init();
			api.ReadHook = ReadHook;
			api.ExecHook = ExecHook;
			api.WriteHook = WriteHook;

			ScanlineHookManager = new MyScanlineHookManager(this);

			api.CMD_init();

			api.QUERY_set_video_refresh(snes_video_refresh);
			api.QUERY_set_input_poll(snes_input_poll);
			api.QUERY_set_input_state(snes_input_state);
			api.QUERY_set_input_notify(snes_input_notify);
			api.QUERY_set_path_request(snes_path_request);
			
			scanlineStart_cb = new LibsnesApi.snes_scanlineStart_t(snes_scanlineStart);
			tracecb = new LibsnesApi.snes_trace_t(snes_trace);

			soundcb = new LibsnesApi.snes_audio_sample_t(snes_audio_sample);
			api.QUERY_set_audio_sample(soundcb);

			RefreshPalette();

			// start up audio resampler
			InitAudio();

			//strip header
			if(romData != null)
				if ((romData.Length & 0x7FFF) == 512)
				{
					var newData = new byte[romData.Length - 512];
					Array.Copy(romData, 512, newData, 0, newData.Length);
					romData = newData;
				}

			if (game["SGB"])
			{
				IsSGB = true;
				SystemId = "SNES";
				BoardName = "SGB";

				CurrLoadParams = new LoadParams()
				{
					type = LoadParamType.SuperGameBoy,
					rom_xml = null,
					rom_data = sgbRomData,
					rom_size = (uint)sgbRomData.Length,
					dmg_xml = null,
					dmg_data = romData,
					dmg_size = (uint)romData.Length
				};

				if (!LoadCurrent())
					throw new Exception("snes_load_cartridge_normal() failed");
			}
			else
			{
				//we may need to get some information out of the cart, even during the following bootup/load process
				if (xmlData != null)
				{
					romxml = new System.Xml.XmlDocument();
					romxml.Load(new MemoryStream(xmlData));

					//bsnes wont inspect the xml to load the necessary sfc file.
					//so, we have to do that here and pass it in as the romData :/
					if (romxml["cartridge"] != null && romxml["cartridge"]["rom"] != null)
						romData = File.ReadAllBytes(CoreComm.CoreFileProvider.PathSubfile(romxml["cartridge"]["rom"].Attributes["name"].Value));
					else
						throw new Exception("Could not find rom file specification in xml file. Please check the integrity of your xml file");
				}

				SystemId = "SNES";
				CurrLoadParams = new LoadParams()
				{
					type = LoadParamType.Normal,
					xml_data = xmlData,
					rom_data = romData
				};

				if(!LoadCurrent())
					throw new Exception("snes_load_cartridge_normal() failed");
			}

			if (api.QUERY_get_region() == LibsnesApi.SNES_REGION.NTSC)
			{
				//similar to what aviout reports from snes9x and seems logical from bsnes first principles. bsnes uses that numerator (ntsc master clockrate) for sure.
				CoreComm.VsyncNum = 21477272;
				CoreComm.VsyncDen = 4 * 341 * 262;
			}
			else
			{
				//http://forums.nesdev.com/viewtopic.php?t=5367&start=19
				CoreComm.VsyncNum = 21281370;
				CoreComm.VsyncDen = 4 * 341 * 312;
			}

			CoreComm.CpuTraceAvailable = true;

			api.CMD_power();

			SetupMemoryDomains(romData,sgbRomData);

			DeterministicEmulation = deterministicEmulation;
			if (DeterministicEmulation) // save frame-0 savestate now
			{
				MemoryStream ms = new MemoryStream();
				BinaryWriter bw = new BinaryWriter(ms);
				bw.Write(CoreSaveState());
				bw.Write(true); // framezero, so no controller follows and don't frameadvance on load
				// hack: write fake dummy controller info
				bw.Write(new byte[536]);
				bw.Close();
				savestatebuff = ms.ToArray();
			}
		}
예제 #2
0
        public LibsnesCore(GameInfo game, byte[] romData, byte[] xmlData, CoreComm comm, object settings, object syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            ServiceProvider = ser;

            _tracer = new TraceBuffer
            {
                Header = "65816: PC, mnemonic, operands, registers (A, X, Y, S, D, DB, flags (NVMXDIZC), V, H)"
            };

            ser.Register <IDisassemblable>(new W65816_DisassemblerService());

            _game    = game;
            CoreComm = comm;
            byte[] sgbRomData = null;

            if (game["SGB"])
            {
                if ((romData[0x143] & 0xc0) == 0xc0)
                {
                    throw new CGBNotSupportedException();
                }

                sgbRomData        = CoreComm.CoreFileProvider.GetFirmware("SNES", "Rom_SGB", true, "SGB Rom is required for SGB emulation.");
                game.FirmwareHash = sgbRomData.HashSHA1();
            }

            _settings     = (SnesSettings)settings ?? new SnesSettings();
            _syncSettings = (SnesSyncSettings)syncSettings ?? new SnesSyncSettings();

            // TODO: pass profile here
            Api = new LibsnesApi(CoreComm.CoreFileProvider.DllPath())
            {
                ReadHook  = ReadHook,
                ExecHook  = ExecHook,
                WriteHook = WriteHook
            };

            ScanlineHookManager = new MyScanlineHookManager(this);

            _controllerDeck = new LibsnesControllerDeck(_syncSettings);
            _controllerDeck.NativeInit(Api);

            Api.CMD_init();

            Api.QUERY_set_path_request(snes_path_request);

            _scanlineStartCb = new LibsnesApi.snes_scanlineStart_t(snes_scanlineStart);
            _tracecb         = new LibsnesApi.snes_trace_t(snes_trace);

            _soundcb = new LibsnesApi.snes_audio_sample_t(snes_audio_sample);

            // start up audio resampler
            InitAudio();
            ser.Register <ISoundProvider>(_resampler);

            // strip header
            if ((romData?.Length & 0x7FFF) == 512)
            {
                var newData = new byte[romData.Length - 512];
                Array.Copy(romData, 512, newData, 0, newData.Length);
                romData = newData;
            }

            if (game["SGB"])
            {
                IsSGB    = true;
                SystemId = "SNES";
                ser.Register <IBoardInfo>(new SGBBoardInfo());

                _currLoadParams = new LoadParams()
                {
                    type     = LoadParamType.SuperGameBoy,
                    rom_xml  = null,
                    rom_data = sgbRomData,
                    rom_size = (uint)sgbRomData.Length,
                    dmg_data = romData,
                };

                if (!LoadCurrent())
                {
                    throw new Exception("snes_load_cartridge_normal() failed");
                }
            }
            else
            {
                // we may need to get some information out of the cart, even during the following bootup/load process
                if (xmlData != null)
                {
                    _romxml = new XmlDocument();
                    _romxml.Load(new MemoryStream(xmlData));

                    // bsnes wont inspect the xml to load the necessary sfc file.
                    // so, we have to do that here and pass it in as the romData :/
                    if (_romxml["cartridge"]?["rom"] != null)
                    {
                        romData = File.ReadAllBytes(CoreComm.CoreFileProvider.PathSubfile(_romxml["cartridge"]["rom"].Attributes["name"].Value));
                    }
                    else
                    {
                        throw new Exception("Could not find rom file specification in xml file. Please check the integrity of your xml file");
                    }
                }

                SystemId        = "SNES";
                _currLoadParams = new LoadParams
                {
                    type     = LoadParamType.Normal,
                    xml_data = xmlData,
                    rom_data = romData
                };

                if (!LoadCurrent())
                {
                    throw new Exception("snes_load_cartridge_normal() failed");
                }
            }

            if (Api.Region == LibsnesApi.SNES_REGION.NTSC)
            {
                // similar to what aviout reports from snes9x and seems logical from bsnes first principles. bsnes uses that numerator (ntsc master clockrate) for sure.
                VsyncNumerator   = 21477272;
                VsyncDenominator = 4 * 341 * 262;
            }
            else
            {
                // http://forums.nesdev.com/viewtopic.php?t=5367&start=19
                VsyncNumerator   = 21281370;
                VsyncDenominator = 4 * 341 * 312;
            }

            Api.CMD_power();

            SetupMemoryDomains(romData, sgbRomData);

            if (CurrentProfile == "Compatibility")
            {
                ser.Register <ITraceable>(_tracer);
            }

            Api.QUERY_set_path_request(null);
            Api.QUERY_set_video_refresh(snes_video_refresh);
            Api.QUERY_set_input_poll(snes_input_poll);
            Api.QUERY_set_input_state(snes_input_state);
            Api.QUERY_set_input_notify(snes_input_notify);
            Api.QUERY_set_audio_sample(_soundcb);
            Api.Seal();
            RefreshPalette();
        }
예제 #3
0
        public LibsnesCore(GameInfo game, byte[] romData, bool deterministicEmulation, byte[] xmlData, CoreComm comm, object Settings, object SyncSettings)
        {
            CoreComm = comm;
            byte[] sgbRomData = null;
            if (game["SGB"])
            {
                if ((romData[0x143] & 0xc0) == 0xc0)
                {
                    throw new CGBNotSupportedException();
                }
                sgbRomData        = CoreComm.CoreFileProvider.GetFirmware("SNES", "Rom_SGB", true, "SGB Rom is required for SGB emulation.");
                game.FirmwareHash = sgbRomData.HashSHA1();
            }

            this.Settings     = (SnesSettings)Settings ?? new SnesSettings();
            this.SyncSettings = (SnesSyncSettings)SyncSettings ?? new SnesSyncSettings();

            api = new LibsnesApi(GetExePath());
            api.CMD_init();
            api.ReadHook  = ReadHook;
            api.ExecHook  = ExecHook;
            api.WriteHook = WriteHook;

            ScanlineHookManager = new MyScanlineHookManager(this);

            api.CMD_init();

            api.QUERY_set_video_refresh(snes_video_refresh);
            api.QUERY_set_input_poll(snes_input_poll);
            api.QUERY_set_input_state(snes_input_state);
            api.QUERY_set_input_notify(snes_input_notify);
            api.QUERY_set_path_request(snes_path_request);

            scanlineStart_cb = new LibsnesApi.snes_scanlineStart_t(snes_scanlineStart);
            tracecb          = new LibsnesApi.snes_trace_t(snes_trace);

            soundcb = new LibsnesApi.snes_audio_sample_t(snes_audio_sample);
            api.QUERY_set_audio_sample(soundcb);

            RefreshPalette();

            // start up audio resampler
            InitAudio();

            //strip header
            if (romData != null)
            {
                if ((romData.Length & 0x7FFF) == 512)
                {
                    var newData = new byte[romData.Length - 512];
                    Array.Copy(romData, 512, newData, 0, newData.Length);
                    romData = newData;
                }
            }

            if (game["SGB"])
            {
                IsSGB     = true;
                SystemId  = "SNES";
                BoardName = "SGB";

                CurrLoadParams = new LoadParams()
                {
                    type     = LoadParamType.SuperGameBoy,
                    rom_xml  = null,
                    rom_data = sgbRomData,
                    rom_size = (uint)sgbRomData.Length,
                    dmg_xml  = null,
                    dmg_data = romData,
                    dmg_size = (uint)romData.Length
                };

                if (!LoadCurrent())
                {
                    throw new Exception("snes_load_cartridge_normal() failed");
                }
            }
            else
            {
                //we may need to get some information out of the cart, even during the following bootup/load process
                if (xmlData != null)
                {
                    romxml = new System.Xml.XmlDocument();
                    romxml.Load(new MemoryStream(xmlData));

                    //bsnes wont inspect the xml to load the necessary sfc file.
                    //so, we have to do that here and pass it in as the romData :/
                    if (romxml["cartridge"] != null && romxml["cartridge"]["rom"] != null)
                    {
                        romData = File.ReadAllBytes(CoreComm.CoreFileProvider.PathSubfile(romxml["cartridge"]["rom"].Attributes["name"].Value));
                    }
                    else
                    {
                        throw new Exception("Could not find rom file specification in xml file. Please check the integrity of your xml file");
                    }
                }

                SystemId       = "SNES";
                CurrLoadParams = new LoadParams()
                {
                    type     = LoadParamType.Normal,
                    xml_data = xmlData,
                    rom_data = romData
                };

                if (!LoadCurrent())
                {
                    throw new Exception("snes_load_cartridge_normal() failed");
                }
            }

            if (api.QUERY_get_region() == LibsnesApi.SNES_REGION.NTSC)
            {
                //similar to what aviout reports from snes9x and seems logical from bsnes first principles. bsnes uses that numerator (ntsc master clockrate) for sure.
                CoreComm.VsyncNum = 21477272;
                CoreComm.VsyncDen = 4 * 341 * 262;
            }
            else
            {
                //http://forums.nesdev.com/viewtopic.php?t=5367&start=19
                CoreComm.VsyncNum = 21281370;
                CoreComm.VsyncDen = 4 * 341 * 312;
            }

            CoreComm.CpuTraceAvailable = true;

            api.CMD_power();

            SetupMemoryDomains(romData, sgbRomData);

            DeterministicEmulation = deterministicEmulation;
            if (DeterministicEmulation)             // save frame-0 savestate now
            {
                MemoryStream ms = new MemoryStream();
                BinaryWriter bw = new BinaryWriter(ms);
                bw.Write(CoreSaveState());
                bw.Write(true);                 // framezero, so no controller follows and don't frameadvance on load
                // hack: write fake dummy controller info
                bw.Write(new byte[536]);
                bw.Close();
                savestatebuff = ms.ToArray();
            }
        }