NES: infrastructure stuff

This commit is contained in:
goyuken 2014-03-04 23:18:10 +00:00
parent 197ca96630
commit 804fed9375
3 changed files with 134 additions and 12 deletions

View File

@ -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)
{

View File

@ -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<string, string>(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));
}
}

View File

@ -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<string>(Buttons) };
@ -168,8 +170,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
public ControllerNES(bool famicomP2)
{
if (famicomP2)
Definition = new ControllerDefinition
{ BoolButtons = new List<string>(FamicomP2Buttons.Where((s) => s != null)) };
Definition = new ControllerDefinition { BoolButtons = new List<string>(FamicomP2Buttons.Where((s) => s != null)) };
else
Definition = new ControllerDefinition { BoolButtons = new List<string>(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));
}
/// <summary>
/// handles all player number merging
/// </summary>
@ -970,4 +971,121 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
}
#endregion
#region settings
public class NESControlSettings
{
static readonly Dictionary<string, Type> FamicomExpansions;
static readonly Dictionary<string, Type> NesPortDevices;
static Dictionary<string, Type> Implementors<T>()
{
var assy = typeof(NESControlSettings).Assembly;
var types = assy.GetTypes().Where(c => typeof(T).IsAssignableFrom(c));
var ret = new Dictionary<string, Type>();
foreach (Type t in types)
ret[t.Name] = t;
return ret;
}
static NESControlSettings()
{
FamicomExpansions = Implementors<IFamicomExpansion>();
NesPortDevices = Implementors<INesPort>();
}
public static IList<string> GetFamicomExpansionValues()
{
return new List<string>(FamicomExpansions.Keys).AsReadOnly();
}
public static IList<string> GetNesPortValues()
{
return new List<string>(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<int, int, bool> 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
}