diff --git a/BizHawk.Client.Common/lua/EmuLuaLibrary.Events.cs b/BizHawk.Client.Common/lua/EmuLuaLibrary.Events.cs index ced5e63d01..0d968f100c 100644 --- a/BizHawk.Client.Common/lua/EmuLuaLibrary.Events.cs +++ b/BizHawk.Client.Common/lua/EmuLuaLibrary.Events.cs @@ -3,7 +3,8 @@ using System.Linq; using System.ComponentModel; using LuaInterface; - +using BizHawk.Emulation.Common; +using BizHawk.Emulation.Common.IEmulatorExtensions; namespace BizHawk.Client.Common { @@ -155,7 +156,27 @@ namespace BizHawk.Client.Common { var nlf = new NamedLuaFunction(luaf, "OnInputPoll", LogOutputCallback, CurrentThread, name); _luaFunctions.Add(nlf); - Global.Emulator.CoreComm.InputCallback.Add(nlf.Callback); + + if (Global.Emulator.CanPollInput()) + { + try + { + (Global.Emulator as IInputPollable).InputCallbacks.Add(nlf.Callback); + } + catch (NotImplementedException) + { + LogNotImplemented(); + } + } + else + { + LogNotImplemented(); + } + } + + private void LogNotImplemented() + { + Log(string.Format("Error: {0} does not yet implement input polling callbacks")); } [LuaMethodAttributes( diff --git a/BizHawk.Client.Common/lua/LuaFunctionList.cs b/BizHawk.Client.Common/lua/LuaFunctionList.cs index a9959d2d68..d7bce3c587 100644 --- a/BizHawk.Client.Common/lua/LuaFunctionList.cs +++ b/BizHawk.Client.Common/lua/LuaFunctionList.cs @@ -1,6 +1,9 @@ using System.Collections.Generic; using System.Linq; +using BizHawk.Emulation.Common; +using BizHawk.Emulation.Common.IEmulatorExtensions; + namespace BizHawk.Client.Common { public class LuaFunctionList : List @@ -15,14 +18,22 @@ namespace BizHawk.Client.Common public new bool Remove(NamedLuaFunction function) { - Global.Emulator.CoreComm.InputCallback.Remove(function.Callback); + if (Global.Emulator.CanPollInput()) + { + (Global.Emulator as IInputPollable).InputCallbacks.Remove(function.Callback); + } + Global.Emulator.CoreComm.MemoryCallbackSystem.Remove(function.Callback); return base.Remove(function); } public void ClearAll() { - Global.Emulator.CoreComm.InputCallback.RemoveAll(this.Select(x => x.Callback)); + if (Global.Emulator.CanPollInput()) + { + (Global.Emulator as IInputPollable).InputCallbacks.RemoveAll(this.Select(x => x.Callback)); + } + Global.Emulator.CoreComm.MemoryCallbackSystem.RemoveAll(this.Select(x => x.Callback)); Clear(); } diff --git a/BizHawk.Emulation.Common/Base Implementations/InputCallbackSystem.cs b/BizHawk.Emulation.Common/Base Implementations/InputCallbackSystem.cs new file mode 100644 index 0000000000..d4bb90aa28 --- /dev/null +++ b/BizHawk.Emulation.Common/Base Implementations/InputCallbackSystem.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; + +namespace BizHawk.Emulation.Common +{ + public class InputCallbackSystem : List, IInputCallbackSystem + { + public void Call() + { + foreach (var action in this) + { + action(); + } + } + + public void RemoveAll(IEnumerable actions) + { + foreach (var action in actions) + { + this.Remove(action); + } + } + } +} diff --git a/BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj b/BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj index 5df5c5e884..0910275921 100644 --- a/BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj +++ b/BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj @@ -50,6 +50,7 @@ VersionInfo.cs + @@ -67,6 +68,7 @@ + diff --git a/BizHawk.Emulation.Common/CoreComms.cs b/BizHawk.Emulation.Common/CoreComms.cs index af0ce43dd4..caea890579 100644 --- a/BizHawk.Emulation.Common/CoreComms.cs +++ b/BizHawk.Emulation.Common/CoreComms.cs @@ -14,11 +14,6 @@ namespace BizHawk.Emulation.Common /// public TraceBuffer Tracer = new TraceBuffer(); - /// - /// for emu.on_snoop() - /// - public InputCallbackSystem InputCallback = new InputCallbackSystem(); - public MemoryCallbackSystem MemoryCallbackSystem = new MemoryCallbackSystem(); public double VsyncRate @@ -121,25 +116,6 @@ namespace BizHawk.Emulation.Common private bool logging; } - public class InputCallbackSystem : List - { - public void Call() - { - foreach (var action in this) - { - action(); - } - } - - public void RemoveAll(IEnumerable actions) - { - foreach (var action in actions) - { - this.Remove(action); - } - } - } - public class MemoryCallbackSystem { private readonly List _reads = new List(); diff --git a/BizHawk.Emulation.Common/Interfaces/IInputCallbackSystem.cs b/BizHawk.Emulation.Common/Interfaces/IInputCallbackSystem.cs new file mode 100644 index 0000000000..82204f8ad7 --- /dev/null +++ b/BizHawk.Emulation.Common/Interfaces/IInputCallbackSystem.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; + +namespace BizHawk.Emulation.Common +{ + // TODO: This isn't a CoreService, it is a sub class of a core service, it would be nice to make that clear + public interface IInputCallbackSystem : IList + { + /// + /// Will iterate and call every callback + /// + void Call(); + + /// + /// Will remove the given list of callbacks + /// + void RemoveAll(IEnumerable actions); + } +} diff --git a/BizHawk.Emulation.Common/Interfaces/IInputPollable.cs b/BizHawk.Emulation.Common/Interfaces/IInputPollable.cs index 7fe8495c66..c539206720 100644 --- a/BizHawk.Emulation.Common/Interfaces/IInputPollable.cs +++ b/BizHawk.Emulation.Common/Interfaces/IInputPollable.cs @@ -12,5 +12,7 @@ /// All cores should define it the same, a lag frame is a frame in which input was not polled. /// bool IsLagFrame { get; } + + IInputCallbackSystem InputCallbacks { get; } } } diff --git a/BizHawk.Emulation.Cores/Calculator/TI83.IInputPollable.cs b/BizHawk.Emulation.Cores/Calculator/TI83.IInputPollable.cs index 75f3bdf51e..22927c62ee 100644 --- a/BizHawk.Emulation.Cores/Calculator/TI83.IInputPollable.cs +++ b/BizHawk.Emulation.Cores/Calculator/TI83.IInputPollable.cs @@ -14,6 +14,8 @@ namespace BizHawk.Emulation.Cores.Calculators set { _lagCount = value; } } + public IInputCallbackSystem InputCallbacks { get; private set; } + public bool IsLagFrame { get { return _isLag; } diff --git a/BizHawk.Emulation.Cores/Calculator/TI83.cs b/BizHawk.Emulation.Cores/Calculator/TI83.cs index 0a38ac2d0d..21726c2cfa 100644 --- a/BizHawk.Emulation.Cores/Calculator/TI83.cs +++ b/BizHawk.Emulation.Cores/Calculator/TI83.cs @@ -52,6 +52,7 @@ namespace BizHawk.Emulation.Cores.Calculators [CoreConstructor("TI83")] public TI83(CoreComm comm, GameInfo game, byte[] rom, object Settings) { + InputCallbacks = new InputCallbackSystem(); PutSettings((TI83Settings)Settings ?? new TI83Settings()); CoreComm = comm; @@ -186,7 +187,7 @@ namespace BizHawk.Emulation.Cores.Calculators private byte ReadKeyboard() { - CoreComm.InputCallback.Call(); + InputCallbacks.Call(); //ref TI-9X int ret = 0xFF; diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/C64.Input.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/C64.Input.cs index 4aa9981b1a..096002f352 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/C64.Input.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/C64.Input.cs @@ -32,7 +32,7 @@ public void PollInput() { - _c64.CoreComm.InputCallback.Call(); + _c64.InputCallbacks.Call(); // scan joysticks pollIndex = 0; for (int j = 0; j < 5; j++) diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/C64.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/C64.cs index 4dfd702286..c86e98d02c 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/C64.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/C64.cs @@ -186,6 +186,9 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 public bool BinarySaveStatesPreferred { get { return false; } } + private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); + public IInputCallbackSystem InputCallbacks { get { return _inputCallbacks; } } + private void SetupMemoryDomains() { // chips must be initialized before this code runs! diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.Core.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.Core.cs index 85344800cc..784fd0fdd5 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.Core.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.Core.cs @@ -424,7 +424,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 public byte ReadControls1(bool peek) { - CoreComm.InputCallback.Call(); + InputCallbacks.Call(); byte value = 0xFF; if (Controller["P1 Up"]) { value &= 0xEF; } @@ -443,7 +443,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 public byte ReadControls2(bool peek) { - CoreComm.InputCallback.Call(); + InputCallbacks.Call(); byte value = 0xFF; if (Controller["P2 Up"]) { value &= 0xEF; } diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.IInputPollable.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.IInputPollable.cs index ebf520c533..efe6e472c9 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.IInputPollable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.IInputPollable.cs @@ -15,6 +15,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 get { return _islag; } } + public IInputCallbackSystem InputCallbacks { get; private set; } + private bool _islag = true; private int _lagcount; } diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs index 5ec78d6507..8b72367118 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs @@ -24,6 +24,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 [CoreConstructor("A26")] public Atari2600(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings) { + InputCallbacks = new InputCallbackSystem(); Ram = new byte[128]; CoreComm = comm; Settings = (A2600Settings)settings ?? new A2600Settings(); @@ -137,7 +138,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 // give the emu a minimal of input\output connections so it doesn't crash var comm = new CoreComm(null, null); - comm.InputCallback = new InputCallbackSystem(); + using (Atari2600 emu = new Atari2600(new CoreComm(null, null), newgame, rom, null, null)) { emu.Controller = new NullController(); diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/7800/Atari7800.IInputPollable.cs b/BizHawk.Emulation.Cores/Consoles/Atari/7800/Atari7800.IInputPollable.cs index 4ceeceadc3..74937501de 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/7800/Atari7800.IInputPollable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/7800/Atari7800.IInputPollable.cs @@ -15,6 +15,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800 get { return _islag; } } + public IInputCallbackSystem InputCallbacks { get; private set; } + private bool _islag = true; private int _lagcount; } diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/7800/Atari7800.cs b/BizHawk.Emulation.Cores/Consoles/Atari/7800/Atari7800.cs index 9fc7f5f562..040fe3de51 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/7800/Atari7800.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/7800/Atari7800.cs @@ -122,6 +122,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800 public Atari7800(CoreComm comm, GameInfo game, byte[] rom, string GameDBfn) { + InputCallbacks = new InputCallbackSystem(); CoreComm = comm; byte[] highscoreBIOS = comm.CoreFileProvider.GetFirmware("A78", "Bios_HSC", false, "Some functions may not work without the high score BIOS."); byte[] pal_bios = comm.CoreFileProvider.GetFirmware("A78", "Bios_PAL", false, "The game will not run if the correct region BIOS is not available."); @@ -186,7 +187,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800 logger); theMachine.Reset(); - theMachine.InputState.InputPollCallback = CoreComm.InputCallback.Call; + theMachine.InputState.InputPollCallback = InputCallbacks.Call; ControlAdapter = new Atari7800Control(theMachine); ControllerDefinition = ControlAdapter.ControlType; diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/lynx/Lynx.cs b/BizHawk.Emulation.Cores/Consoles/Atari/lynx/Lynx.cs index 6c86a7c80d..a405422192 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/lynx/Lynx.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/lynx/Lynx.cs @@ -139,6 +139,14 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx public int LagCount { get; set; } public bool IsLagFrame { get; private set; } + private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); + + // TODO: optimize managed to unmanaged using the ActiveChanged event + public IInputCallbackSystem InputCallbacks + { + [FeatureNotImplemented]get { return _inputCallbacks; } + } + public string SystemId { get { return "Lynx"; } } public bool DeterministicEmulation { get { return true; } } diff --git a/BizHawk.Emulation.Cores/Consoles/Coleco/ColecoVision.cs b/BizHawk.Emulation.Cores/Consoles/Coleco/ColecoVision.cs index bbb0460dbc..85342d7b6a 100644 --- a/BizHawk.Emulation.Cores/Consoles/Coleco/ColecoVision.cs +++ b/BizHawk.Emulation.Cores/Consoles/Coleco/ColecoVision.cs @@ -60,6 +60,9 @@ namespace BizHawk.Emulation.Cores.ColecoVision SetupMemoryDomains(); } + private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); + public IInputCallbackSystem InputCallbacks { get { return _inputCallbacks; } } + public MemoryDomainList MemoryDomains { get { return memoryDomains; } } MemoryDomainList memoryDomains; const ushort RamSizeMask = 0x03FF; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.cs index 9162d54efb..81a802f3d4 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.cs @@ -87,6 +87,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA public int Frame { get; private set; } public int LagCount { get; set; } public bool IsLagFrame { get; private set; } + + private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); + + // TODO: optimize managed to unmanaged using the ActiveChanged event + public IInputCallbackSystem InputCallbacks { [FeatureNotImplemented]get { return _inputCallbacks; } } + public string SystemId { get { return "GBA"; } } public bool DeterministicEmulation { get { return true; } } @@ -309,7 +315,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA LibMeteor.Buttons GetInput() { - CoreComm.InputCallback.Call(); + InputCallbacks.Call(); // libmeteor bitflips everything itself, so 0 == off, 1 == on IsLagFrame = false; LibMeteor.Buttons ret = 0; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/VBANext.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/VBANext.cs index 8f4a5d251a..b6dd6a530a 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/VBANext.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/VBANext.cs @@ -109,6 +109,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA public int LagCount { get; set; } public bool IsLagFrame { get; private set; } + private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); + + // TODO: optimize managed to unmanaged using the ActiveChanged event + public IInputCallbackSystem InputCallbacks { [FeatureNotImplemented]get { return _inputCallbacks; } } + public string SystemId { get { return "GBA"; } } public bool DeterministicEmulation { get; private set; } @@ -272,7 +277,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA void InitCallbacks() { - padcb = new LibVBANext.StandardCallback(() => CoreComm.InputCallback.Call()); + padcb = new LibVBANext.StandardCallback(() => InputCallbacks.Call()); fetchcb = new LibVBANext.AddressCallback((addr) => CoreComm.MemoryCallbackSystem.CallExecute(addr)); readcb = new LibVBANext.AddressCallback((addr) => CoreComm.MemoryCallbackSystem.CallRead(addr)); writecb = new LibVBANext.AddressCallback((addr) => CoreComm.MemoryCallbackSystem.CallWrite(addr)); @@ -281,7 +286,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA void SyncCallbacks() { - LibVBANext.SetPadCallback(Core, CoreComm.InputCallback.Any() ? padcb : null); + LibVBANext.SetPadCallback(Core, InputCallbacks.Any() ? padcb : null); LibVBANext.SetFetchCallback(Core, CoreComm.MemoryCallbackSystem.HasExecutes ? fetchcb : null); LibVBANext.SetReadCallback(Core, CoreComm.MemoryCallbackSystem.HasReads ? readcb : null); LibVBANext.SetWriteCallback(Core, CoreComm.MemoryCallbackSystem.HasWrites ? writecb : null); diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs index afd93c46fb..5f70243a26 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs @@ -36,6 +36,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy public int LagCount { get; set; } public bool IsLagFrame { get; private set; } + private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); + + // TODO: optimize managed to unmanaged using the ActiveChanged event + public IInputCallbackSystem InputCallbacks { [FeatureNotImplemented]get { return _inputCallbacks; } } + // all cycle counts are relative to a 2*1024*1024 mhz refclock /// @@ -222,7 +227,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy LibGambatte.Buttons ControllerCallback() { - CoreComm.InputCallback.Call(); + InputCallbacks.Call(); IsLagFrame = false; return CurrentButtons; } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.cs index 36ba2f5113..956ca4f150 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.cs @@ -79,10 +79,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy SetMemoryDomains(); - L.CoreComm.InputCallback = CoreComm.InputCallback; - R.CoreComm.InputCallback = CoreComm.InputCallback; + foreach (var callback in InputCallbacks) + { + L.InputCallbacks.Add(callback); + R.InputCallbacks.Add(callback); + } } + private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); + + // TODO: optimize managed to unmanaged using the ActiveChanged event + public IInputCallbackSystem InputCallbacks { [FeatureNotImplemented]get { return _inputCallbacks; } } + public IVideoProvider VideoProvider { get { return this; } } public ISoundProvider SoundProvider { get { return null; } } public ISyncSoundProvider SyncSoundProvider { get { return this; } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs index 2a9cc9fe56..cb856a631a 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs @@ -121,7 +121,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 // 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); + _inputProvider = new N64Input(this as IInputPollable, api, comm, this._syncSettings.Controllers); string rsp = _syncSettings.Rsp == N64SyncSettings.RspType.Rsp_Hle ? @@ -410,6 +410,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 api.setWriteCallback(writecb); } + private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); + + // TODO: optimize managed to unmanaged using the ActiveChanged event + public IInputCallbackSystem InputCallbacks { [FeatureNotImplemented]get { return _inputCallbacks; } } + #endregion } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64Input.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64Input.cs index 0a2b2f7c2f..b19f2c5bb0 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64Input.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64Input.cs @@ -48,8 +48,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 } }; - public N64Input(mupen64plusApi core, CoreComm comm, N64SyncSettings.N64ControllerSettings[] controllerSettings) + private readonly IInputPollable _emuCore; + + public N64Input(IInputPollable emuCore, mupen64plusApi core, CoreComm comm, N64SyncSettings.N64ControllerSettings[] controllerSettings) { + _emuCore = emuCore; api = new mupen64plusInputApi(core); CoreComm = comm; @@ -81,7 +84,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 /// Id of controller to update and shove public int GetControllerInput(int i) { - CoreComm.InputCallback.Call(); + _emuCore.InputCallbacks.Call(); ThisFrameInputPolled = true; // Analog stick right = +X diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Core.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Core.cs index b7379bb98a..83ecade106 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Core.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Core.cs @@ -420,7 +420,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES byte read_joyport(int addr) { - CoreComm.InputCallback.Call(); + InputCallbacks.Call(); lagged = false; byte ret = addr == 0x4016 ? ControllerDeck.ReadA(Controller) : ControllerDeck.ReadB(Controller); ret &= 0x1f; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs index c6229ef34a..c29499d30e 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs @@ -322,10 +322,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES public int LagCount { get { return _lagcount; } set { _lagcount = value; } } public bool IsLagFrame { get { return islag; } } + private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); + public IInputCallbackSystem InputCallbacks { get { return _inputCallbacks; } } + public bool DeterministicEmulation { get { return true; } } - - public byte[] CloneSaveRam() { if (board is FDS) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs index ab27154c93..98f9121046 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs @@ -392,6 +392,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES #endregion + public IInputCallbackSystem InputCallbacks { [FeatureNotImplemented]get { throw new NotImplementedException(); } } + #region bootgod public RomStatus? BootGodStatus { get; private set; } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs index b20c7620a6..302cc3d41f 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs @@ -241,6 +241,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES }; } + private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); + + // TODO: optimize managed to unmanaged using the ActiveChanged event + public IInputCallbackSystem InputCallbacks { [FeatureNotImplemented]get { return _inputCallbacks; } } + [FeatureNotImplemented] public void SetCpuRegister(string register, int value) { @@ -440,7 +445,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES { // as this is implemented right now, only P1 and P2 normal controllers work - CoreComm.InputCallback.Call(); + InputCallbacks.Call(); //Console.WriteLine("{0} {1} {2} {3}", port, device, index, id); string key = "P" + (1 + port) + " "; diff --git a/BizHawk.Emulation.Cores/Consoles/PC Engine/Input.cs b/BizHawk.Emulation.Cores/Consoles/PC Engine/Input.cs index d221ab0479..f50ed0a41f 100644 --- a/BizHawk.Emulation.Cores/Consoles/PC Engine/Input.cs +++ b/BizHawk.Emulation.Cores/Consoles/PC Engine/Input.cs @@ -64,7 +64,7 @@ namespace BizHawk.Emulation.Cores.PCEngine byte ReadInput() { - CoreComm.InputCallback.Call(); + InputCallbacks.Call(); byte value = 0x3F; int player = SelectedController + 1; diff --git a/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.cs b/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.cs index f4907748e9..b41a00f86b 100644 --- a/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.cs +++ b/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.cs @@ -295,6 +295,9 @@ namespace BizHawk.Emulation.Cores.PCEngine public int LagCount { get { return lagCount; } set { lagCount = value; } } public bool IsLagFrame { get { return isLag; } } + private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); + public IInputCallbackSystem InputCallbacks { get { return _inputCallbacks; } } + public void ResetCounters() { // this should just be a public setter instead of a new method. diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Genesis.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Genesis.cs index e61ca290ea..3b133c2964 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Genesis.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Genesis.cs @@ -45,6 +45,9 @@ namespace BizHawk.Emulation.Cores.Sega.Genesis private SoundMixer SoundMixer; + [FeatureNotImplemented] + public IInputCallbackSystem InputCallbacks { get { throw new NotImplementedException(); } } + public void ResetCounters() { Frame = 0; diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/IO.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/IO.cs index c7089b3655..b28fcb87f2 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/IO.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/IO.cs @@ -108,7 +108,7 @@ namespace BizHawk.Emulation.Cores.Sega.Genesis void ReadController(ref byte data) { - CoreComm.InputCallback.Call(); + InputCallbacks.Call(); data &= 0xC0; if ((data & 0x40) != 0) // TH high { diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/Input.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/Input.cs index a542078f71..5e1f6d0e97 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/Input.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/Input.cs @@ -42,7 +42,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem byte ReadControls1() { - CoreComm.InputCallback.Call(); + InputCallbacks.Call(); lagged = false; byte value = 0xFF; @@ -61,7 +61,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem byte ReadControls2() { - CoreComm.InputCallback.Call(); + InputCallbacks.Call(); lagged = false; byte value = 0xFF; diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs index 5b85649f8d..19af1df9fa 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs @@ -78,6 +78,10 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem public int Frame { get { return frame; } set { frame = value; } } public int LagCount { get { return lagCount; } set { lagCount = value; } } public bool IsLagFrame { get { return isLag; } } + + private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); + public IInputCallbackSystem InputCallbacks { get { return _inputCallbacks; } } + byte Port01 = 0xFF; byte Port02 = 0xFF; byte Port3E = 0xAF; diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs index a09f015185..1f9460a895 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs @@ -74,7 +74,7 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn ActivateGL(); Init(bios); - InputCallbackH = new LibYabause.InputCallback(() => CoreComm.InputCallback.Call()); + InputCallbackH = new LibYabause.InputCallback(() => InputCallbacks.Call()); LibYabause.libyabause_setinputcallback(InputCallbackH); CoreComm.UsesDriveLed = true; @@ -292,6 +292,11 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn public int LagCount { get; set; } public bool IsLagFrame { get; private set; } + private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); + + // TODO: optimize managed to unmanaged using the ActiveChanged event + public IInputCallbackSystem InputCallbacks { [FeatureNotImplemented]get { return _inputCallbacks; } } + public string SystemId { get { return "SAT"; } } public bool DeterministicEmulation { get { return true; } } diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs index 052f0abac1..b1e90dbd0c 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs @@ -375,10 +375,15 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx // core callback for input void input_callback() { - CoreComm.InputCallback.Call(); + InputCallbacks.Call(); IsLagFrame = false; } + private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); + + // TODO: optimize managed to unmanaged using the ActiveChanged event + public IInputCallbackSystem InputCallbacks { [FeatureNotImplemented]get { return _inputCallbacks; } } + #endregion // TODO: use render and rendersound diff --git a/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs b/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs index d7d107a76f..689ead4912 100644 --- a/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs +++ b/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs @@ -175,6 +175,10 @@ namespace BizHawk.Emulation.Cores.WonderSwan public int LagCount { get; set; } public bool IsLagFrame { get; private set; } + private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); + + // TODO: optimize managed to unmanaged using the ActiveChanged event + public IInputCallbackSystem InputCallbacks { [FeatureNotImplemented]get { return _inputCallbacks; } } public string SystemId { get { return "WSWAN"; } } public bool DeterministicEmulation { get; private set; } @@ -351,7 +355,7 @@ namespace BizHawk.Emulation.Cores.WonderSwan } void ButtonCallback() { - CoreComm.InputCallback.Call(); + InputCallbacks.Call(); } void InitDebugCallbacks() @@ -369,7 +373,7 @@ namespace BizHawk.Emulation.Cores.WonderSwan CoreComm.MemoryCallbackSystem.HasWrites ? WriteCallbackD : null, CoreComm.MemoryCallbackSystem.HasExecutes ? ExecCallbackD : null); BizSwan.bizswan_setbuttoncallback(Core, - CoreComm.InputCallback.Any() ? ButtonCallbackD : null); + InputCallbacks.Any() ? ButtonCallbackD : null); } #endregion