From 804fed93752b85979dd74a870ca3fae9cbbd97b2 Mon Sep 17 00:00:00 2001 From: goyuken Date: Tue, 4 Mar 2014 23:18:10 +0000 Subject: [PATCH] NES: infrastructure stuff --- .../Consoles/Nintendo/NES/Core.cs | 6 +- .../Consoles/Nintendo/NES/NES.cs | 8 +- .../Consoles/Nintendo/NES/NESControllers.cs | 132 +++++++++++++++++- 3 files changed, 134 insertions(+), 12 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Core.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Core.cs index 15cb7367e6..376498c472 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Core.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Core.cs @@ -42,6 +42,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES int[] palette_compiled = new int[64*8]; // new input system + NESControlSettings ControllerSettings; // this is stored internally so that a new change of settings won't replace IControllerDeck ControllerDeck; byte latched4016; @@ -181,10 +182,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES // wire controllers // todo: allow changing this - ControllerDeck = new NesDeck( - new ControllerNES(), - new ControllerNES(), - ppu.LightGunCallback); + ControllerDeck = ControllerSettings.Instantiate(ppu.LightGunCallback); // set controller definition first time only if (ControllerDefinition == null) { diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs index af703e7fe8..89110ea40b 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs @@ -27,6 +27,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES } this.SyncSettings = (NESSyncSettings)SyncSettings ?? new NESSyncSettings(); + this.ControllerSettings = this.SyncSettings.Controls; CoreComm = comm; CoreComm.CpuTraceAvailable = true; BootGodDB.Initialize(); @@ -922,16 +923,21 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES public Region RegionOverride = Region.Default; + public NESControlSettings Controls = new NESControlSettings(); + public NESSyncSettings Clone() { var ret = (NESSyncSettings)MemberwiseClone(); ret.BoardProperties = new Dictionary(BoardProperties); + ret.Controls = Controls.Clone(); return ret; } public static bool NeedsReboot(NESSyncSettings x, NESSyncSettings y) { - return !(Util.DictionaryEqual(x.BoardProperties, y.BoardProperties) && x.RegionOverride == y.RegionOverride); + return !(Util.DictionaryEqual(x.BoardProperties, y.BoardProperties) && + x.RegionOverride == y.RegionOverride && + !NESControlSettings.NeedsReboot(x.Controls, y.Controls)); } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NESControllers.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NESControllers.cs index d0782c489f..ac8c473ddc 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NESControllers.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NESControllers.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Text; using BizHawk.Emulation.Common; using BizHawk.Common; +using System.Reflection; +using Newtonsoft.Json; namespace BizHawk.Emulation.Cores.Nintendo.NES { @@ -159,7 +161,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES bool FamicomP2Hack; ControllerDefinition Definition; - + public ControllerNES() { Definition = new ControllerDefinition { BoolButtons = new List(Buttons) }; @@ -168,8 +170,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES public ControllerNES(bool famicomP2) { if (famicomP2) - Definition = new ControllerDefinition - { BoolButtons = new List(FamicomP2Buttons.Where((s) => s != null)) }; + Definition = new ControllerDefinition { BoolButtons = new List(FamicomP2Buttons.Where((s) => s != null)) }; else Definition = new ControllerDefinition { BoolButtons = new List(Buttons) }; FamicomP2Hack = famicomP2; @@ -353,7 +354,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES latched3 >>= 1; // ASR not LSR, so endless stream of 1s after data latched4 >>= 1; } - return (byte)(d3 << 3| d4 << 4); + return (byte)(d3 << 3 | d4 << 4); } public ControllerDefinition GetDefinition() @@ -376,7 +377,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES static ControllerDefinition Definition = new ControllerDefinition { BoolButtons = { "0Fire" }, - FloatControls = { "0Zapper X", "0Zapper Y"}, + FloatControls = { "0Zapper X", "0Zapper Y" }, FloatRanges = { new[] { 0.0f, 128.0f, 255.0f }, new[] { 0.0f, 120.0f, 239.0f } } }; @@ -542,7 +543,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES } } - public class FamilyBasicKeyboard: IFamicomExpansion + public class FamilyBasicKeyboard : IFamicomExpansion { #region buttonlookup static string[] Buttons = @@ -933,7 +934,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES plrnext = currplr + 1; return string.Format("P{0} {1}", currplr, input.Substring(1)); } - + /// /// handles all player number merging /// @@ -970,4 +971,121 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES } #endregion + + #region settings + + public class NESControlSettings + { + static readonly Dictionary FamicomExpansions; + static readonly Dictionary NesPortDevices; + + static Dictionary Implementors() + { + var assy = typeof(NESControlSettings).Assembly; + var types = assy.GetTypes().Where(c => typeof(T).IsAssignableFrom(c)); + var ret = new Dictionary(); + foreach (Type t in types) + ret[t.Name] = t; + return ret; + } + + static NESControlSettings() + { + FamicomExpansions = Implementors(); + NesPortDevices = Implementors(); + } + + public static IList GetFamicomExpansionValues() + { + return new List(FamicomExpansions.Keys).AsReadOnly(); + } + public static IList GetNesPortValues() + { + return new List(NesPortDevices.Keys).AsReadOnly(); + } + + [JsonIgnore] + private bool _Famicom; + public bool Famicom { get { return _Famicom; } set { _Famicom = value; } } + [JsonIgnore] + private string _NesLeftPort; + [JsonIgnore] + private string _NesRightPort; + public string NesLeftPort + { + get { return _NesLeftPort; } + set + { + if (NesPortDevices.ContainsKey(value)) + _NesLeftPort = value; + else + throw new InvalidOperationException(); + } + } + public string NesRightPort + { + get { return _NesRightPort; } + set + { + if (NesPortDevices.ContainsKey(value)) + _NesRightPort = value; + else + throw new InvalidOperationException(); + } + } + [JsonIgnore] + private string _FamicomExpPort; + public string FamicomExpPort + { + get { return _FamicomExpPort; } + set + { + if (FamicomExpansions.ContainsKey(value)) + _FamicomExpPort = value; + else + throw new InvalidOperationException(); + } + } + + public NESControlSettings() + { + Famicom = false; + FamicomExpPort = typeof(UnpluggedFam).Name; + NesLeftPort = typeof(ControllerNES).Name; + NesRightPort = typeof(ControllerNES).Name; + } + + public static bool NeedsReboot(NESControlSettings x, NESControlSettings y) + { + return + x.Famicom != y.Famicom || + x.FamicomExpPort != y.FamicomExpPort || + x.NesLeftPort != y.NesLeftPort || + x.NesRightPort != y.NesRightPort; + } + + public NESControlSettings Clone() + { + return (NESControlSettings)MemberwiseClone(); + } + + public IControllerDeck Instantiate(Func PPUCallback) + { + if (Famicom) + { + IFamicomExpansion exp = (IFamicomExpansion)Activator.CreateInstance(FamicomExpansions[FamicomExpPort]); + IControllerDeck ret = new FamicomDeck(exp, PPUCallback); + return ret; + } + else + { + INesPort left = (INesPort)Activator.CreateInstance(NesPortDevices[NesLeftPort]); + INesPort right = (INesPort)Activator.CreateInstance(NesPortDevices[NesRightPort]); + IControllerDeck ret = new NesDeck(left, right, PPUCallback); + return ret; + } + } + } + + #endregion }