move movie input logic from InputManager to MovieSession, multitrack is broken currently, will fix later

This commit is contained in:
adelikat 2020-06-07 13:03:22 -05:00
parent fefdf0d60a
commit 8c5538405f
11 changed files with 54 additions and 45 deletions

View File

@ -5,7 +5,7 @@ namespace BizHawk.Client.Common
/// <summary> /// <summary>
/// Just copies source to sink, or returns whatever a NullController would if it is disconnected. useful for immovable hard-points. /// Just copies source to sink, or returns whatever a NullController would if it is disconnected. useful for immovable hard-points.
/// </summary> /// </summary>
public class CopyControllerAdapter : IController public class CopyControllerAdapter : IInputAdapter
{ {
public ControllerDefinition Definition => Curr.Definition; public ControllerDefinition Definition => Curr.Definition;

View File

@ -0,0 +1,13 @@
using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common
{
/// <summary>
/// Represents an input adapter, that can take in a source, manipulate it as needed
/// and then represent the resulting state as an <see cref="IController"/>
/// </summary>
public interface IInputAdapter : IController
{
IController Source { get; set; }
}
}

View File

@ -12,11 +12,6 @@ namespace BizHawk.Client.Common
// (1)->Input Display // (1)->Input Display
public class InputManager public class InputManager
{ {
// the movie will be spliced in between these if it is present
public CopyControllerAdapter MovieInputSourceAdapter { get; } = new CopyControllerAdapter();
public CopyControllerAdapter MovieOutputHardpoint { get; } = new CopyControllerAdapter();
public MultitrackRewiringControllerAdapter MultitrackRewiringAdapter { get; } = new MultitrackRewiringControllerAdapter();
// the original source controller, bound to the user, sort of the "input" port for the chain, i think // the original source controller, bound to the user, sort of the "input" port for the chain, i think
public Controller ActiveController { get; set; } // TODO: private setter, add a method that takes both controllers in public Controller ActiveController { get; set; } // TODO: private setter, add a method that takes both controllers in
@ -26,7 +21,7 @@ namespace BizHawk.Client.Common
// the "output" port for the controller chain. // the "output" port for the controller chain.
public CopyControllerAdapter ControllerOutput { get; } = new CopyControllerAdapter(); public CopyControllerAdapter ControllerOutput { get; } = new CopyControllerAdapter();
public UdlrControllerAdapter UdLRControllerAdapter { get; } = new UdlrControllerAdapter(); private UdlrControllerAdapter UdLRControllerAdapter { get; } = new UdlrControllerAdapter();
public AutoFireStickyXorAdapter AutofireStickyXorAdapter { get; } = new AutoFireStickyXorAdapter(); public AutoFireStickyXorAdapter AutofireStickyXorAdapter { get; } = new AutoFireStickyXorAdapter();
@ -51,7 +46,7 @@ namespace BizHawk.Client.Common
public Controller ClientControls { get; set; } public Controller ClientControls { get; set; }
public void SyncControls(IEmulator emulator, Config config) public void SyncControls(IEmulator emulator, IMovieSession session, Config config)
{ {
var def = emulator.ControllerDefinition; var def = emulator.ControllerDefinition;
@ -73,14 +68,8 @@ namespace BizHawk.Client.Common
StickyXorAdapter.Source = UdLRControllerAdapter; StickyXorAdapter.Source = UdLRControllerAdapter;
AutofireStickyXorAdapter.Source = StickyXorAdapter; AutofireStickyXorAdapter.Source = StickyXorAdapter;
MultitrackRewiringAdapter.Source = AutofireStickyXorAdapter; session.MovieIn.Source = AutofireStickyXorAdapter;
MovieInputSourceAdapter.Source = MultitrackRewiringAdapter; ControllerOutput.Source = session.MovieOut;
ControllerOutput.Source = MovieOutputHardpoint;
Global.MovieSession.RecreateMovieController(MovieInputSourceAdapter.Definition);
// connect the movie session before MovieOutputHardpoint
MovieOutputHardpoint.Source = Global.MovieSession.MovieController;
} }
private static Controller BindToDefinition(ControllerDefinition def, IDictionary<string, Dictionary<string, string>> allBinds, IDictionary<string, Dictionary<string, AnalogBind>> analogBinds) private static Controller BindToDefinition(ControllerDefinition def, IDictionary<string, Dictionary<string, string>> allBinds, IDictionary<string, Dictionary<string, AnalogBind>> analogBinds)

View File

@ -107,7 +107,7 @@ namespace BizHawk.Client.Common
} }
} }
public class AutoFireStickyXorAdapter : IStickyController public class AutoFireStickyXorAdapter : IStickyController, IInputAdapter
{ {
public ControllerDefinition Definition => Source.Definition; public ControllerDefinition Definition => Source.Definition;

View File

@ -39,6 +39,8 @@ namespace BizHawk.Client.Common
?? throw new ArgumentNullException($"{nameof(pauseCallback)} cannot be null."); ?? throw new ArgumentNullException($"{nameof(pauseCallback)} cannot be null.");
_modeChangedCallback = modeChangedCallback _modeChangedCallback = modeChangedCallback
?? throw new ArgumentNullException($"{nameof(modeChangedCallback)} CannotUnloadAppDomainException be null."); ?? throw new ArgumentNullException($"{nameof(modeChangedCallback)} CannotUnloadAppDomainException be null.");
MultiTrack.RewiringAdapter.Source = MovieIn;
} }
public IMovieConfig Settings { get; } public IMovieConfig Settings { get; }
@ -50,15 +52,13 @@ namespace BizHawk.Client.Common
public bool NewMovieQueued => _queuedMovie != null; public bool NewMovieQueued => _queuedMovie != null;
public string QueuedSyncSettings => _queuedMovie.SyncSettingsJson; public string QueuedSyncSettings => _queuedMovie.SyncSettingsJson;
public IInputAdapter MovieIn { get; } = new CopyControllerAdapter();
public IInputAdapter MovieOut { get; } = new CopyControllerAdapter();
public IMovieController MovieController { get; private set; } = new Bk2Controller("", NullController.Instance.Definition); public IMovieController MovieController { get; private set; } = new Bk2Controller("", NullController.Instance.Definition);
public MultitrackRecorder MultiTrack { get; } = new MultitrackRecorder(); public MultitrackRecorder MultiTrack { get; } = new MultitrackRecorder();
public void RecreateMovieController(ControllerDefinition definition)
{
MovieController = new Bk2Controller(definition);
}
public IMovieController GenerateMovieController(ControllerDefinition definition = null) public IMovieController GenerateMovieController(ControllerDefinition definition = null)
{ {
// TODO: expose Movie.LogKey and pass in here // TODO: expose Movie.LogKey and pass in here
@ -233,6 +233,7 @@ namespace BizHawk.Client.Common
public void RunQueuedMovie(bool recordMode, IEmulator emulator, IDictionary<string, string> preferredCores) public void RunQueuedMovie(bool recordMode, IEmulator emulator, IDictionary<string, string> preferredCores)
{ {
MovieController = new Bk2Controller(emulator.ControllerDefinition);
_queuedMovie.Attach(emulator); _queuedMovie.Attach(emulator);
foreach (var previousPref in _preferredCores) foreach (var previousPref in _preferredCores)
{ {
@ -255,8 +256,6 @@ namespace BizHawk.Client.Common
{ {
Movie.StartNewPlayback(); Movie.StartNewPlayback();
} }
MultiTrack.Restart(emulator.ControllerDefinition.PlayerCount);
} }
public void ToggleMultitrack() public void ToggleMultitrack()
@ -350,9 +349,9 @@ namespace BizHawk.Client.Common
private void LatchInputToMultitrackUser() private void LatchInputToMultitrackUser()
{ {
var rewiredSource = Global.InputManager.MultitrackRewiringAdapter;
if (MultiTrack.IsActive) if (MultiTrack.IsActive)
{ {
var rewiredSource = MultiTrack.RewiringAdapter;
rewiredSource.PlayerSource = 1; rewiredSource.PlayerSource = 1;
rewiredSource.PlayerTargetMask = 1 << MultiTrack.CurrentPlayer; rewiredSource.PlayerTargetMask = 1 << MultiTrack.CurrentPlayer;
if (MultiTrack.RecordAll) if (MultiTrack.RecordAll)
@ -372,7 +371,8 @@ namespace BizHawk.Client.Common
private void LatchInputToUser() private void LatchInputToUser()
{ {
MovieController.SetFrom(Global.InputManager.MovieInputSourceAdapter); MovieOut.Source = MovieIn;
MovieController.SetFrom(MovieIn); // TODO: this shouldn't be necessary anymore
} }
// Latch input from the input log, if available // Latch input from the input log, if available
@ -393,10 +393,7 @@ namespace BizHawk.Client.Common
} }
MovieController.SetFrom(input); MovieController.SetFrom(input);
if (MultiTrack.IsActive) MovieOut.Source = MovieController;
{
Global.InputManager.MultitrackRewiringAdapter.Source = MovieController;
}
} }
private void HandlePlaybackEnd() private void HandlePlaybackEnd()
@ -438,6 +435,7 @@ namespace BizHawk.Client.Common
// we don't want TasMovie to latch user input outside its internal recording mode, so limit it to autohold // we don't want TasMovie to latch user input outside its internal recording mode, so limit it to autohold
if (Movie is ITasMovie && Movie.IsPlayingOrFinished()) if (Movie is ITasMovie && Movie.IsPlayingOrFinished())
{ {
// TODO: same as MovieIn, since autofiresitcky is the last in the chain before movie
MovieController.SetFromSticky(Global.InputManager.AutofireStickyXorAdapter); MovieController.SetFromSticky(Global.InputManager.AutofireStickyXorAdapter);
} }
else else
@ -452,9 +450,7 @@ namespace BizHawk.Client.Common
} }
} }
// the movie session makes sure that the correct input has been read and merged to its MovieControllerAdapter; Movie.RecordFrame(Movie.Emulator.Frame, MovieController);
// this has been wired to Global.MovieOutputHardpoint in RewireInputChain
Movie.RecordFrame(Movie.Emulator.Frame, Global.InputManager.MovieOutputHardpoint);
} }
} }
} }

View File

@ -9,6 +9,8 @@ namespace BizHawk.Client.Common
Restart(1); Restart(1);
} }
internal MultitrackRewiringControllerAdapter RewiringAdapter { get; } = new MultitrackRewiringControllerAdapter();
public bool IsActive { get; set; } public bool IsActive { get; set; }
public int CurrentPlayer { get; private set; } public int CurrentPlayer { get; private set; }
public int PlayerCount { get; private set; } public int PlayerCount { get; private set; }
@ -84,10 +86,10 @@ namespace BizHawk.Client.Common
/// <summary> /// <summary>
/// rewires player1 controls to playerN /// rewires player1 controls to playerN
/// </summary> /// </summary>
public class MultitrackRewiringControllerAdapter : IController public class MultitrackRewiringControllerAdapter : IInputAdapter
{ {
public IController Source { get; set; } public IController Source { get; set; }
public int PlayerSource { get; set; } = 1; public int PlayerSource { get; set; } = -1;
public int PlayerTargetMask { get; set; } public int PlayerTargetMask { get; set; }
public ControllerDefinition Definition => Source.Definition; public ControllerDefinition Definition => Source.Definition;

View File

@ -14,7 +14,7 @@ namespace BizHawk.Client.Common
{ {
writer.WriteLine("[Input]"); writer.WriteLine("[Input]");
var lg = new Bk2LogEntryGenerator(LogKey, Global.InputManager.MovieOutputHardpoint); var lg = new Bk2LogEntryGenerator(LogKey, Session.MovieController);
writer.WriteLine(lg.GenerateLogKey()); writer.WriteLine(lg.GenerateLogKey());
foreach (var record in Log) foreach (var record in Log)

View File

@ -24,10 +24,18 @@ namespace BizHawk.Client.Common
MultitrackRecorder MultiTrack { get; } MultitrackRecorder MultiTrack { get; }
/// <summary> /// <summary>
/// Recreates MovieController with the given controller definition /// Represents the input source that is fed to
/// with an empty controller state /// the movie for the purpsoe of recording, if active,
/// or to simply pass through if inactive
/// </summary> /// </summary>
void RecreateMovieController(ControllerDefinition definition); IInputAdapter MovieIn { get; }
/// <summary>
/// Represents the movie input in the input chain
/// Is a pass through when movies are not active,
/// otherwise they handle necessary movie logic
/// </summary>
IInputAdapter MovieOut { get; }
/// <summary> /// <summary>
/// Creates a <see cref="IMovieController" /> instance based on the /// Creates a <see cref="IMovieController" /> instance based on the

View File

@ -275,10 +275,11 @@ namespace BizHawk.Client.Common
int oldLength = InputLogLength; int oldLength = InputLogLength;
ChangeLog.AddGeneralUndo(oldLength, oldLength + numFrames - 1); ChangeLog.AddGeneralUndo(oldLength, oldLength + numFrames - 1);
// TODO: same as MovieIn, since autofiresitcky is the last in the chain before movie
Session.MovieController.SetFromSticky(Global.InputManager.AutofireStickyXorAdapter); Session.MovieController.SetFromSticky(Global.InputManager.AutofireStickyXorAdapter);
// account for autohold. needs autohold pattern to be already recorded in the current frame // account for autohold. needs autohold pattern to be already recorded in the current frame
var lg = LogGeneratorInstance(Global.InputManager.MovieOutputHardpoint); var lg = LogGeneratorInstance(Session.MovieController);
for (int i = 0; i < numFrames; i++) for (int i = 0; i < numFrames; i++)
{ {

View File

@ -932,7 +932,7 @@ namespace BizHawk.Client.EmuHawk
{ {
AddOnScreenMessage("Controller settings saved"); AddOnScreenMessage("Controller settings saved");
InitControls(); InitControls();
InputManager.SyncControls(Emulator, Config); InputManager.SyncControls(Emulator, MovieSession, Config);
} }
else else
{ {
@ -947,7 +947,7 @@ namespace BizHawk.Client.EmuHawk
{ {
AddOnScreenMessage("Hotkey settings saved"); AddOnScreenMessage("Hotkey settings saved");
InitControls(); InitControls();
InputManager.SyncControls(Emulator, Config); InputManager.SyncControls(Emulator, MovieSession, Config);
} }
else else
{ {

View File

@ -413,7 +413,7 @@ namespace BizHawk.Client.EmuHawk
} }
Sound.StartSound(); Sound.StartSound();
InputManager.SyncControls(Emulator, Config); InputManager.SyncControls(Emulator, MovieSession, Config);
GlobalWin.CheatList = new CheatCollection(Config.Cheats); GlobalWin.CheatList = new CheatCollection(Config.Cheats);
CheatList.Changed += Tools.UpdateCheatRelatedTools; CheatList.Changed += Tools.UpdateCheatRelatedTools;
RewireSound(); RewireSound();
@ -2845,7 +2845,7 @@ namespace BizHawk.Client.EmuHawk
Config = ConfigService.Load<Config>(iniPath); Config = ConfigService.Load<Config>(iniPath);
Config.ResolveDefaults(); Config.ResolveDefaults();
InitControls(); // rebind hotkeys InitControls(); // rebind hotkeys
InputManager.SyncControls(Emulator, Config); InputManager.SyncControls(Emulator, MovieSession, Config);
AddOnScreenMessage($"Config file loaded: {iniPath}"); AddOnScreenMessage($"Config file loaded: {iniPath}");
} }
@ -3706,7 +3706,7 @@ namespace BizHawk.Client.EmuHawk
{ {
string openAdvancedArgs = $"*{OpenAdvancedSerializer.Serialize(ioa)}"; string openAdvancedArgs = $"*{OpenAdvancedSerializer.Serialize(ioa)}";
Emulator = loader.LoadedEmulator; Emulator = loader.LoadedEmulator;
InputManager.SyncControls(Emulator, Config); InputManager.SyncControls(Emulator, MovieSession, Config);
if (oaOpenrom != null && Path.GetExtension(oaOpenrom.Path.Replace("|", "")).ToLowerInvariant() == ".xml" && !(Emulator is LibsnesCore)) if (oaOpenrom != null && Path.GetExtension(oaOpenrom.Path.Replace("|", "")).ToLowerInvariant() == ".xml" && !(Emulator is LibsnesCore))
{ {