/// <summary> /// Creates a N64 Audio subsystem /// </summary> /// <param name="api">Mupen64 api which is used for fetching sound</param> public N64Audio(mupen64plusApi core) { this.api = new mupen64plusAudioApi(core); _samplingRate = api.GetSamplingRate(); Resampler = new SpeexResampler(6, SamplingRate, 44100, SamplingRate, 44100); core.VInterrupt += DoAudioFrame; }
internal N64Input(IInputPollable emuCore, mupen64plusApi core, N64SyncSettings.N64ControllerSettings[] controllerSettings) { _emuCore = emuCore; _api = new mupen64plusInputApi(core); _api.SetM64PInputCallback(GetControllerInput); core.VInterrupt += ShiftInputPolledBools; for (int i = 0; i < controllerSettings.Length; ++i) { SetControllerConnected(i, controllerSettings[i].IsConnected); SetControllerPakType(i, controllerSettings[i].PakType); } }
public N64Input(mupen64plusApi core, CoreComm comm, N64SyncSettings.N64ControllerSettings[] controllerSettings) { api = new mupen64plusInputApi(core); CoreComm = comm; api.SetM64PInputCallback(new mupen64plusInputApi.InputCallback(GetControllerInput)); core.VInterrupt += ShiftInputPolledBools; for (int i = 0; i < controllerSettings.Length; ++i) { SetControllerConnected(i, controllerSettings[i].IsConnected); SetControllerPakType(i, controllerSettings[i].PakType); } }
/// <summary> /// Creates N64 Video system with mupen64plus backend /// </summary> /// <param name="api">mupen64plus DLL that is used</param> public N64VideoProvider(mupen64plusApi core, VideoPluginSettings videosettings) { this.api = new mupen64plusVideoApi(core, videosettings); int width = 0; int height = 0; api.GetScreenDimensions(ref width, ref height); SetBufferSize( width > videosettings.Width ? width : videosettings.Width, height > videosettings.Height ? height : videosettings.Height ); core.BeforeRender += DoVideoFrame; core.BeforeRender += () => { IsVIFrame = true; }; }
public N64(CoreComm comm, GameInfo game, byte[] file, object settings, object syncSettings) { ServiceProvider = new BasicServiceProvider(this); InputCallbacks = new InputCallbackSystem(); _memorycallbacks.CallbackAdded += AddBreakpoint; _memorycallbacks.CallbackRemoved += RemoveBreakpoint; int SaveType = 0; if (game.OptionValue("SaveType") == "EEPROM_16K") { SaveType = 1; } CoreComm = comm; _syncSettings = (N64SyncSettings)syncSettings ?? new N64SyncSettings(); _settings = (N64Settings)settings ?? new N64Settings(); _disableExpansionSlot = _syncSettings.DisableExpansionSlot; // Override the user's expansion slot setting if it is mentioned in the gamedb (it is mentioned but the game MUST have this setting or else not work if (game.OptionValue("expansionpak") != null && game.OptionValue("expansionpak") == "1") { _disableExpansionSlot = false; IsOverridingUserExpansionSlotSetting = true; } byte country_code = file[0x3E]; switch (country_code) { // PAL codes case 0x44: case 0x46: case 0x49: case 0x50: case 0x53: case 0x55: case 0x58: case 0x59: _display_type = DisplayType.PAL; break; // NTSC codes case 0x37: case 0x41: case 0x45: case 0x4a: default: // Fallback for unknown codes _display_type = DisplayType.NTSC; break; } StartThreadLoop(); var videosettings = _syncSettings.GetVPS(game, _settings.VideoSizeX, _settings.VideoSizeY); var coreType = _syncSettings.Core; //zero 19-apr-2014 - added this to solve problem with SDL initialization corrupting the main thread (I think) and breaking subsequent emulators (for example, NES) //not sure why this works... if we put the plugin initializations in here, we get deadlocks in some SDL initialization. doesnt make sense to me... RunThreadAction(() => { api = new mupen64plusApi(this, file, videosettings, SaveType, (int)coreType, _disableExpansionSlot); }); // Order is important because the register with the mupen core _videoProvider = new N64VideoProvider(api, videosettings); _audioProvider = new N64Audio(api); _inputProvider = new N64Input(this.AsInputPollable(), api, comm, this._syncSettings.Controllers); (ServiceProvider as BasicServiceProvider).Register <IVideoProvider>(_videoProvider); (ServiceProvider as BasicServiceProvider).Register <ISoundProvider>(_audioProvider.Resampler); switch (Region) { case DisplayType.NTSC: _videoProvider.VsyncNumerator = 60000; _videoProvider.VsyncDenominator = 1001; break; default: _videoProvider.VsyncNumerator = 50; _videoProvider.VsyncDenominator = 1; break; } string rsp; switch (_syncSettings.Rsp) { default: case N64SyncSettings.RspType.Rsp_Hle: rsp = "mupen64plus-rsp-hle.dll"; break; //case N64SyncSettings.RspType.Rsp_cxd4: // rsp = "mupen64plus-rsp-cxd4.dll"; // break; } api.AttachPlugin(mupen64plusApi.m64p_plugin_type.M64PLUGIN_RSP, rsp); InitMemoryDomains(); //if (_syncSettings.Core != N64SyncSettings.CoreType.Dynarec) { ConnectTracer(); SetBreakpointHandler(); } api.AsyncExecuteEmulator(); // Hack: Saving a state on frame 0 has been shown to not be sync stable. Advance past that frame to avoid the problem. // Advancing 2 frames was chosen to deal with a problem with the dynamic recompiler. The dynarec seems to take 2 frames to set // things up correctly. If a state is loaded on frames 0 or 1 mupen tries to access null pointers and the emulator crashes, so instead // advance past both to again avoid the problem. api.frame_advance(); api.frame_advance(); SetControllerButtons(); }
/// <summary> /// Create mupen64plus Emulator /// </summary> /// <param name="comm">Core communication object</param> /// <param name="game">Game information of game to load</param> /// <param name="rom">Rom that should be loaded</param> /// <param name="SyncSettings">N64SyncSettings object</param> public N64(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings) { int SaveType = 0; if (game.OptionValue("SaveType") == "EEPROM_16K") { SaveType = 1; } CoreComm = comm; _syncSettings = (N64SyncSettings)syncSettings ?? new N64SyncSettings(); _settings = (N64Settings)settings ?? new N64Settings(); byte country_code = rom[0x3E]; switch (country_code) { // PAL codes case 0x44: case 0x46: case 0x49: case 0x50: case 0x53: case 0x55: case 0x58: case 0x59: _display_type = DisplayType.PAL; break; // NTSC codes case 0x37: case 0x41: case 0x45: case 0x4a: default: // Fallback for unknown codes _display_type = DisplayType.NTSC; break; } switch (DisplayType) { case DisplayType.NTSC: comm.VsyncNum = 60000; comm.VsyncDen = 1001; break; default: comm.VsyncNum = 50; comm.VsyncDen = 1; break; } StartThreadLoop(); var videosettings = _syncSettings.GetVPS(game, _settings.VideoSizeX, _settings.VideoSizeY); var coreType = _syncSettings.Core; //zero 19-apr-2014 - added this to solve problem with SDL initialization corrupting the main thread (I think) and breaking subsequent emulators (for example, NES) //not sure why this works... if we put the plugin initializations in here, we get deadlocks in some SDL initialization. doesnt make sense to me... RunThreadAction(() => { api = new mupen64plusApi(this, rom, videosettings, SaveType, (int)coreType); }); // Order is important because the register with the mupen core _videoProvider = new N64VideoProvider(api, videosettings); _audioProvider = new N64Audio(api); _inputProvider = new N64Input(api, comm, this._syncSettings.Controllers); string rsp = _syncSettings.Rsp == N64SyncSettings.RspType.Rsp_Hle ? "mupen64plus-rsp-hle.dll" : "mupen64plus-rsp-z64-hlevideo.dll"; api.AttachPlugin(mupen64plusApi.m64p_plugin_type.M64PLUGIN_RSP, rsp); InitMemoryDomains(); RefreshMemoryCallbacks(); api.AsyncExecuteEmulator(); SetControllerButtons(); }