BizHawk/BizHawk.Client.Common/movie/MultitrackRecording.cs

179 lines
3.4 KiB
C#

using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common
{
public class MultitrackRecorder
{
public MultitrackRecorder()
{
Restart();
}
public bool IsActive { get; set; }
public int CurrentPlayer { get; private set; }
public bool RecordAll { get; private set; }
/// <summary>
/// Gets a user friendly multi-track status
/// </summary>
public string Status
{
get
{
if (!IsActive)
{
return "";
}
if (RecordAll)
{
return "Recording All";
}
if (CurrentPlayer == 0)
{
return "Recording None";
}
return "Recording Player " + CurrentPlayer;
}
}
public void Restart()
{
IsActive = false;
CurrentPlayer = 0;
RecordAll = false;
}
public void SelectAll()
{
CurrentPlayer = 0;
RecordAll = true;
}
public void SelectNone()
{
RecordAll = false;
CurrentPlayer = 0;
}
public void Increment()
{
RecordAll = false;
CurrentPlayer++;
if (CurrentPlayer > Global.Emulator.ControllerDefinition.PlayerCount)
{
CurrentPlayer = 1;
}
}
public void Decrement()
{
RecordAll = false;
CurrentPlayer--;
if (CurrentPlayer < 1)
{
CurrentPlayer = Global.Emulator.ControllerDefinition.PlayerCount;
}
}
}
/// <summary>
/// rewires player1 controls to playerN
/// </summary>
public class MultitrackRewiringControllerAdapter : IController
{
public MultitrackRewiringControllerAdapter()
{
PlayerSource = 1;
}
public IController Source { get; set; }
public int PlayerSource { get; set; }
public int PlayerTargetMask { get; set; }
public ControllerDefinition Definition => Source.Definition;
public bool this[string button] => IsPressed(button);
public bool IsPressed(string button)
{
return Source.IsPressed(RemapButtonName(button));
}
public float GetFloat(string button)
{
return Source.GetFloat(RemapButtonName(button));
}
private string RemapButtonName(string button)
{
// Do we even have a source?
if (PlayerSource == -1)
{
return button;
}
// See if we're being asked for a button that we know how to rewire
var bnp = ButtonNameParser.Parse(button);
if (bnp == null)
{
return button;
}
// Ok, this looks like a normal `P1 Button` type thing. we can handle it
// Were we supposed to replace this one?
int foundPlayerMask = 1 << bnp.PlayerNum;
if ((PlayerTargetMask & foundPlayerMask) == 0)
{
return button;
}
// Ok, we were. swap out the source player and then grab his button
bnp.PlayerNum = PlayerSource;
return bnp.ToString();
}
}
public class ButtonNameParser
{
public static ButtonNameParser Parse(string button)
{
// See if we're being asked for a button that we know how to rewire
var parts = button.Split(' ');
if (parts.Length < 2)
{
return null;
}
if (parts[0][0] != 'P')
{
return null;
}
int player;
if (!int.TryParse(parts[0].Substring(1), out player))
{
return null;
}
return new ButtonNameParser
{
PlayerNum = player,
ButtonPart = button.Substring(parts[0].Length + 1)
};
}
public int PlayerNum { get; set; }
public string ButtonPart { get; private set; }
public override string ToString()
{
return $"P{PlayerNum} {ButtonPart}";
}
}
}