Clean up this spaghetti in NesHawk controller and movie import code

This commit is contained in:
YoshiRulz 2021-12-04 23:40:44 +10:00 committed by James Groom
parent dfbce55707
commit 7881067133
5 changed files with 76 additions and 178 deletions

View File

@ -37,8 +37,7 @@ namespace BizHawk.Client.Common.movie.import
NesLeftPort = nameof(ControllerNES),
NesRightPort = nameof(ControllerNES)
};
_deck = controllerSettings.Instantiate((x, y) => true);
AddDeckControlButtons();
_deck = controllerSettings.Instantiate((x, y) => true).AddSystemToControllerDef();
// 004 4-byte little-endian unsigned int: version number, must be 2
uint version = r.ReadUInt32();
@ -145,7 +144,7 @@ namespace BizHawk.Client.Common.movie.import
// Advance to first byte of input data.
r.BaseStream.Position = firstFrameOffset;
SimpleController controllers = new(_deck.GetDefinition());
SimpleController controllers = new(_deck.ControllerDef);
string[] buttons = { "A", "B", "Select", "Start", "Up", "Down", "Left", "Right" };
bool fds = false;
@ -287,15 +286,5 @@ namespace BizHawk.Client.Common.movie.import
syncSettings.Controls = controllerSettings;
Result.Movie.SyncSettingsJson = ConfigService.SaveWithType(syncSettings);
}
private void AddDeckControlButtons()
{
SimpleController controllers = new(_deck.GetDefinition());
// TODO: FDS
// Yes, this adds them to the deck definition too
controllers.Definition.BoolButtons.Add("Reset");
controllers.Definition.BoolButtons.Add("Power");
}
}
}

View File

@ -27,8 +27,7 @@ namespace BizHawk.Client.Common
NesRightPort = nameof(UnpluggedNES)
};
_deck = controllerSettings.Instantiate((x, y) => true);
AddDeckControlButtons();
_deck = controllerSettings.Instantiate((x, y) => true).AddSystemToControllerDef();
Result.Movie.HeaderEntries[HeaderKeys.Platform] = platform;
@ -123,8 +122,7 @@ namespace BizHawk.Client.Common
if (ParseHeader(line, "port0") == "1")
{
controllerSettings.NesLeftPort = nameof(ControllerNES);
_deck = controllerSettings.Instantiate((x, y) => false);
AddDeckControlButtons();
_deck = controllerSettings.Instantiate((x, y) => false).AddSystemToControllerDef();
}
}
else if (line.ToLower().StartsWith("port1"))
@ -132,8 +130,7 @@ namespace BizHawk.Client.Common
if (ParseHeader(line, "port1") == "1")
{
controllerSettings.NesRightPort = nameof(ControllerNES);
_deck = controllerSettings.Instantiate((x, y) => false);
AddDeckControlButtons();
_deck = controllerSettings.Instantiate((x, y) => false).AddSystemToControllerDef();
}
}
else if (line.ToLower().StartsWith("port2"))
@ -153,7 +150,7 @@ namespace BizHawk.Client.Common
controllerSettings.NesRightPort = nameof(FourScore);
}
_deck = controllerSettings.Instantiate((x, y) => false);
_deck = controllerSettings.Instantiate((x, y) => false)/*.AddSystemToControllerDef()*/; //TODO call omitted on purpose? --yoshi
}
else
{
@ -170,7 +167,7 @@ namespace BizHawk.Client.Common
private readonly string[] _buttons = { "Right", "Left", "Down", "Up", "Start", "Select", "B", "A" };
private void ImportInputFrame(string line)
{
SimpleController controllers = new(_deck.GetDefinition());
SimpleController controllers = new(_deck.ControllerDef);
string[] sections = line.Split(new[] {'|'}, StringSplitOptions.RemoveEmptyEntries);
controllers["Reset"] = sections[1][0] == '1';
@ -213,16 +210,6 @@ namespace BizHawk.Client.Common
Result.Movie.AppendFrame(controllers);
}
private void AddDeckControlButtons()
{
SimpleController controllers = new(_deck.GetDefinition());
// TODO: FDS
// Yes, this adds them to the deck definition too
controllers.Definition.BoolButtons.Add("Reset");
controllers.Definition.BoolButtons.Add("Power");
}
private static string ImportTextSubtitle(string line)
{
line = SingleSpaces(line);
@ -273,4 +260,16 @@ namespace BizHawk.Client.Common
}
}
}
internal static class NESHelpers
{
public static IControllerDeck AddSystemToControllerDef(this IControllerDeck deck)
{
var def = deck.ControllerDef;
//TODO FDS
def.BoolButtons.Add("Reset");
def.BoolButtons.Add("Power");
return deck;
}
}
}

View File

@ -94,13 +94,11 @@ namespace BizHawk.Client.Common.movie.import
NesLeftPort = controller1 ? nameof(ControllerNES) : nameof(UnpluggedNES),
NesRightPort = controller2 ? nameof(ControllerNES) : nameof(UnpluggedNES)
};
_deck = controllerSettings.Instantiate((x, y) => true);
_deck = controllerSettings.Instantiate((x, y) => true).AddSystemToControllerDef();
syncSettings.Controls.NesLeftPort = controllerSettings.NesLeftPort;
syncSettings.Controls.NesRightPort = controllerSettings.NesRightPort;
AddDeckControlButtons();
SimpleController controllers = new(_deck.GetDefinition());
SimpleController controllers = new(_deck.ControllerDef);
/*
* 01 Right
@ -161,17 +159,5 @@ namespace BizHawk.Client.Common.movie.import
Result.Movie.SyncSettingsJson = ConfigService.SaveWithType(syncSettings);
}
private void AddDeckControlButtons()
{
SimpleController controllers = new(_deck.GetDefinition());
// TODO: FDS
// Yes, this adds them to the deck definition too
controllers.Definition.BoolButtons.Add("Reset");
controllers.Definition.BoolButtons.Add("Power");
}
}
}

View File

@ -145,16 +145,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
ram = new byte[0x800];
CIRAM = new byte[0x800];
// wire controllers
// todo: allow changing this
ControllerDeck = ControllerSettings.Instantiate(ppu.LightGunCallback);
// set controller definition first time only
if (ControllerDefinition == null)
{
ControllerDefinition = new ControllerDefinition(ControllerDeck.GetDefinition())
{
Name = "NES Controller"
};
ControllerDeck = ControllerSettings.Instantiate(ppu.LightGunCallback); // this assignment was outside the conditional for some reason? --yoshi
ControllerDefinition = ControllerDeck.ControllerDef;
// controls other than the deck
ControllerDefinition.BoolButtons.Add("Power");

View File

@ -70,6 +70,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
/// </summary>
public interface IControllerDeck
{
/// <remarks>
/// implementations create a single <see cref="ControllerDefinition"/> in their ctors and will always return a reference to it;
/// caller may mutate it
/// </remarks>
ControllerDefinition ControllerDef { get; }
/// <summary>
/// call whenever $4016 is written
/// </summary>
@ -84,7 +90,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
/// </summary>
/// <returns>bits 0-4 are valid</returns>
byte ReadB(IController c); // D0:D4
ControllerDefinition GetDefinition();
void SyncState(Serializer ser);
}
@ -93,6 +99,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
/// </summary>
public interface IFamicomExpansion
{
ControllerDefinition ControllerDefFragment { get; }
void Strobe(StrobeInfo s, IController c);
/// <summary>
/// read data from $4016
@ -104,7 +112,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
/// </summary>
/// <returns>bits 1-4 are valid</returns>
byte ReadB(IController c);
ControllerDefinition GetDefinition();
void SyncState(Serializer ser);
}
@ -113,9 +121,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
/// </summary>
public interface INesPort
{
ControllerDefinition ControllerDefFragment { get; }
void Strobe(StrobeInfo s, IController c); // only uses OUT0
byte Read(IController c); // only uses D0, D3, D4
ControllerDefinition GetDefinition();
void SyncState(Serializer ser);
}
@ -128,13 +138,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
private readonly INesPort _right;
private readonly ControlDefUnMerger _leftU;
private readonly ControlDefUnMerger _rightU;
private readonly ControllerDefinition _definition;
public ControllerDefinition ControllerDef { get; }
public NesDeck(INesPort left, INesPort right, LightgunDelegate ppuCallback)
{
_left = left;
_right = right;
_definition = ControllerDefinitionMerger.GetMerged(new[] { left.GetDefinition(), right.GetDefinition() }, out var cdum);
ControllerDef = ControllerDefinitionMerger.GetMerged(
new[] { left.ControllerDefFragment, right.ControllerDefFragment },
out var cdum);
ControllerDef.Name = "NES Controller";
_leftU = cdum[0];
_rightU = cdum[1];
@ -167,11 +181,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return (byte)(_right.Read(_rightU.UnMerge(c)) & 0x19);
}
public ControllerDefinition GetDefinition()
{
return _definition;
}
public void SyncState(Serializer ser)
{
ser.BeginSection(nameof(_left));
@ -185,6 +194,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
public class UnpluggedNES : INesPort
{
public ControllerDefinition ControllerDefFragment { get; } = new();
public void Strobe(StrobeInfo s, IController c)
{
}
@ -194,11 +205,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return 0;
}
public ControllerDefinition GetDefinition()
{
return new ControllerDefinition();
}
public void SyncState(Serializer ser)
{
}
@ -224,16 +230,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
private readonly bool _famicomP2Hack;
private readonly ControllerDefinition _definition;
public ControllerDefinition ControllerDefFragment { get; }
public ControllerNES()
{
_definition = new ControllerDefinition
{
BoolButtons = Buttons
.OrderBy(x => _buttonOrdinals[x])
.ToList()
};
ControllerDefFragment = new() { BoolButtons = Buttons.OrderBy(x => _buttonOrdinals[x]).ToList() };
}
@ -253,22 +254,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{
if (famicomP2)
{
_definition = new ControllerDefinition
{
BoolButtons = FamicomP2Buttons
.Where((s) => s != null)
.OrderBy(x => _buttonOrdinals[x])
.ToList()
};
ControllerDefFragment = new() { BoolButtons = FamicomP2Buttons.Where(static s => s is not null).OrderBy(x => _buttonOrdinals[x]).ToList() };
}
else
{
_definition = new ControllerDefinition
{
BoolButtons = Buttons
.OrderBy(x => _buttonOrdinals[x])
.ToList()
};
ControllerDefFragment = new() { BoolButtons = Buttons.OrderBy(x => _buttonOrdinals[x]).ToList() };
}
_famicomP2Hack = famicomP2;
@ -301,11 +291,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return ret;
}
public ControllerDefinition GetDefinition()
{
return _definition;
}
public void SyncState(Serializer ser)
{
ser.Sync(nameof(_resetting), ref _resetting);
@ -327,15 +312,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
"0A", "0X", "0L", "0R", null, null, null, null // 4 0s at end
};
private readonly ControllerDefinition _definition;
public ControllerSNES()
{
_definition = new ControllerDefinition
{
BoolButtons = Buttons.Where(s => s != null).ToList()
};
}
public ControllerDefinition ControllerDefFragment { get; }
= new() { BoolButtons = Buttons.Where(static s => s is not null).ToList() };
// reset is not edge triggered; so long as it's high, the latch is continuously reloading
// so we need to latch in two places:
@ -364,11 +342,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return ret;
}
public ControllerDefinition GetDefinition()
{
return _definition;
}
public void SyncState(Serializer ser)
{
ser.Sync(nameof(_resetting), ref _resetting);
@ -385,7 +358,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
private bool _resetting;
private byte _latchedValue = 0x54 ^ 0xff;
private static readonly ControllerDefinition Definition
public ControllerDefinition ControllerDefFragment { get; }
= new ControllerDefinition { BoolButtons = { "0Fire" } }
.AddAxis("0Paddle", 0.RangeTo(160), 80);
@ -414,11 +387,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return ret;
}
public ControllerDefinition GetDefinition()
{
return Definition;
}
public void SyncState(Serializer ser)
{
ser.Sync(nameof(_shiftidx), ref _shiftidx);
@ -440,7 +408,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
"1A", "1B", "1Select", "1Start", "1Up", "1Down", "1Left", "1Right",
};
private static readonly ControllerDefinition Definition = new ControllerDefinition { BoolButtons = new List<string>(Buttons) };
public ControllerDefinition ControllerDefFragment { get; }
= new() { BoolButtons = Buttons.ToList() };
private bool _resetting;
private int _latchedValue;
@ -473,11 +442,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return ret;
}
public ControllerDefinition GetDefinition()
{
return Definition;
}
public void SyncState(Serializer ser)
{
ser.Sync(nameof(_resetting), ref _resetting);
@ -489,7 +453,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{
private static readonly string[] D3Buttons = { "0PP2", "0PP1", "0PP5", "0PP9", "0PP6", "0PP10", "0PP11", "0PP7" };
private static readonly string[] D4Buttons = { "0PP4", "0PP3", "0PP12", "0PP8" };
private static readonly ControllerDefinition Definition = new ControllerDefinition { BoolButtons = new List<string>(D3Buttons.Concat(D4Buttons)) };
public ControllerDefinition ControllerDefFragment { get; }
= new() { BoolButtons = D3Buttons.Concat(D4Buttons).ToList() };
private bool _resetting;
private int _latched3;
@ -522,11 +488,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return (byte)(d3 << 3 | d4 << 4);
}
public ControllerDefinition GetDefinition()
{
return Definition;
}
public void SyncState(Serializer ser)
{
ser.Sync(nameof(_resetting), ref _resetting);
@ -554,8 +515,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
/// </summary>
public LightgunDelegate PPUCallback { get; set; }
private static readonly ControllerDefinition Definition
= new ControllerDefinition { BoolButtons = { "0Fire" } }.AddZapper("0Zapper {0}");
public ControllerDefinition ControllerDefFragment { get; }
= new ControllerDefinition { BoolButtons = { "0Fire" } }
.AddZapper("0Zapper {0}");
public void Strobe(StrobeInfo s, IController c)
{
@ -572,11 +534,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return ret;
}
public ControllerDefinition GetDefinition()
{
return Definition;
}
public void SyncState(Serializer ser)
{
}
@ -603,8 +560,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
private bool _resetting;
private uint _latchedValue;
private static readonly ControllerDefinition Definition
= new ControllerDefinition { BoolButtons = { "0Fire" } }.AddZapper("0Zapper {0}");
public ControllerDefinition ControllerDefFragment { get; }
= new ControllerDefinition { BoolButtons = { "0Fire" } }
.AddZapper("0Zapper {0}");
private void Latch(IController c)
{
@ -637,11 +595,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return ret;
}
public ControllerDefinition GetDefinition()
{
return Definition;
}
public void SyncState(Serializer ser)
{
ser.Sync(nameof(_resetting), ref _resetting);
@ -671,14 +624,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
private readonly ControlDefUnMerger _player2U;
private readonly ControlDefUnMerger _player3U;
private readonly ControllerDefinition _definition;
public ControllerDefinition ControllerDef { get; }
public FamicomDeck(IFamicomExpansion expSlot, LightgunDelegate ppuCallback)
{
_player3 = expSlot;
_definition = ControllerDefinitionMerger.GetMerged(
new[] { _player1.GetDefinition(), _player2.GetDefinition(), _player3.GetDefinition() }, out var cdum);
_definition.BoolButtons.Add("P2 Microphone");
ControllerDef = ControllerDefinitionMerger.GetMerged(
new[] { _player1.ControllerDefFragment, _player2.ControllerDefFragment, _player3.ControllerDefFragment },
out var cdum);
ControllerDef.BoolButtons.Add("P2 Microphone");
ControllerDef.Name = "NES Controller";
_player1U = cdum[0];
_player2U = cdum[1];
_player3U = cdum[2];
@ -713,11 +668,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return ret;
}
public ControllerDefinition GetDefinition()
{
return _definition;
}
public void SyncState(Serializer ser)
{
ser.BeginSection("Left");
@ -741,7 +691,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
private bool _resetting;
private byte _latchedValue = 0x54 ^ 0xff;
private static readonly ControllerDefinition Definition
public ControllerDefinition ControllerDefFragment { get; }
= new ControllerDefinition { BoolButtons = { "0Fire" } }
.AddAxis("0Paddle", 0.RangeTo(160), 80);
@ -775,11 +725,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return ret;
}
public ControllerDefinition GetDefinition()
{
return Definition;
}
public void SyncState(Serializer ser)
{
ser.Sync(nameof(_shiftidx), ref _shiftidx);
@ -875,7 +820,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
};
private static readonly ControllerDefinition Definition = new ControllerDefinition { BoolButtons = new List<string>(Buttons) };
public ControllerDefinition ControllerDefFragment { get; }
= new() { BoolButtons = Buttons.ToList() };
private bool _active;
private int _column;
@ -919,11 +865,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return ret;
}
public ControllerDefinition GetDefinition()
{
return Definition;
}
public void SyncState(Serializer ser)
{
ser.Sync(nameof(_active), ref _active);
@ -944,7 +885,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
"1A", "1B", "1Select", "1Start", "1Up", "1Down", "1Left", "1Right",
};
private static readonly ControllerDefinition Definition = new ControllerDefinition { BoolButtons = new List<string>(P1Buttons.Concat(P2Buttons)) };
public ControllerDefinition ControllerDefFragment { get; }
= new() { BoolButtons = P1Buttons.Concat(P2Buttons).ToList() };
private bool _resetting;
private int _latchedP1;
@ -983,11 +925,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return ret;
}
public ControllerDefinition GetDefinition()
{
return Definition;
}
public void SyncState(Serializer ser)
{
ser.Sync(nameof(_resetting), ref _resetting);
@ -998,7 +935,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
public class OekaKids : IFamicomExpansion
{
private static readonly ControllerDefinition Definition
public ControllerDefinition ControllerDefFragment { get; }
= new ControllerDefinition { BoolButtons = { "0Click", "0Touch" } }
.AddZapper("0Pen {0}"); // why would a tablet have the same resolution as a CRT monitor? --yoshi
@ -1052,11 +989,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return ret;
}
public ControllerDefinition GetDefinition()
{
return Definition;
}
public void SyncState(Serializer ser)
{
ser.Sync(nameof(_resetting), ref _resetting);
@ -1067,6 +999,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
public class UnpluggedFam : IFamicomExpansion
{
public ControllerDefinition ControllerDefFragment => new();
public void Strobe(StrobeInfo s, IController c)
{
}
@ -1081,11 +1015,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return 0;
}
public ControllerDefinition GetDefinition()
{
return new ControllerDefinition();
}
public void SyncState(Serializer ser)
{
}