Better color coding of input display, auto-holds show red, previous frame shows orange, restore ability to show immediate input, also fix but in autofire-autohold
This commit is contained in:
parent
36c09eea0f
commit
c863d57113
|
@ -37,6 +37,19 @@ namespace BizHawk.Client.Common
|
||||||
return _buttons[button];
|
return _buttons[button];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool AnyPressed
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_buttons.Any(x => x.Value))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _floatButtons.Any(x => x.Value != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public float GetFloat(string name) { return _floatButtons[name]; }
|
public float GetFloat(string name) { return _floatButtons[name]; }
|
||||||
|
|
||||||
// Looks for bindings which are activated by the supplied physical button.
|
// Looks for bindings which are activated by the supplied physical button.
|
||||||
|
|
|
@ -202,7 +202,72 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StickyXorAdapter : IController
|
public class AndAdapter : IController
|
||||||
|
{
|
||||||
|
public bool IsPressed(string button)
|
||||||
|
{
|
||||||
|
return this[button];
|
||||||
|
}
|
||||||
|
|
||||||
|
// pass floats solely from the original source
|
||||||
|
// this works in the code because SourceOr is the autofire controller
|
||||||
|
public float GetFloat(string name) { return Source.GetFloat(name); }
|
||||||
|
|
||||||
|
public IController Source { get; set; }
|
||||||
|
public IController SourceAnd { get; set; }
|
||||||
|
public ControllerDefinition Type { get { return Source.Type; } set { throw new InvalidOperationException(); } }
|
||||||
|
|
||||||
|
public bool this[string button]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Source[button] & SourceAnd[button];
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used by input display, to determine if either autofire or regular stickies are "in effect" because we color this scenario differently
|
||||||
|
public class StickyOrAdapter : IController
|
||||||
|
{
|
||||||
|
public bool IsPressed(string button)
|
||||||
|
{
|
||||||
|
return this[button];
|
||||||
|
}
|
||||||
|
|
||||||
|
// pass floats solely from the original source
|
||||||
|
// this works in the code because SourceOr is the autofire controller
|
||||||
|
public float GetFloat(string name) { return 0.0F; } // Floats don't make sense in sticky land
|
||||||
|
|
||||||
|
public ISticky Source { get; set; }
|
||||||
|
public ISticky SourceStickyOr { get; set; }
|
||||||
|
public ControllerDefinition Type { get { return Source.Type; } set { throw new InvalidOperationException(); } }
|
||||||
|
|
||||||
|
public bool this[string button]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Source.StickyIsInEffect(button) ||
|
||||||
|
SourceStickyOr.StickyIsInEffect(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ISticky : IController
|
||||||
|
{
|
||||||
|
bool StickyIsInEffect(string button);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class StickyXorAdapter : IController, ISticky
|
||||||
{
|
{
|
||||||
protected HashSet<string> stickySet = new HashSet<string>();
|
protected HashSet<string> stickySet = new HashSet<string>();
|
||||||
|
|
||||||
|
@ -216,7 +281,10 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
public bool Locked { get; set; } // Pretty much a hack,
|
public bool Locked { get; set; } // Pretty much a hack,
|
||||||
|
|
||||||
public bool IsPressed(string button) { return this[button]; }
|
public bool IsPressed(string button)
|
||||||
|
{
|
||||||
|
return this[button];
|
||||||
|
}
|
||||||
|
|
||||||
// if SetFloat() is called (typically virtual pads), then that float will entirely override the Source input
|
// if SetFloat() is called (typically virtual pads), then that float will entirely override the Source input
|
||||||
// otherwise, the source is passed thru.
|
// otherwise, the source is passed thru.
|
||||||
|
@ -259,6 +327,20 @@ namespace BizHawk.Client.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines if a sticky is current mashing the button itself,
|
||||||
|
/// If sticky is not set then false, if set, it returns true if the Source is not pressed, else false
|
||||||
|
/// </summary>
|
||||||
|
public bool StickyIsInEffect(string button)
|
||||||
|
{
|
||||||
|
if (IsSticky(button))
|
||||||
|
{
|
||||||
|
return !Source.IsPressed(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void SetSticky(string button, bool isSticky)
|
public void SetSticky(string button, bool isSticky)
|
||||||
{
|
{
|
||||||
if (isSticky)
|
if (isSticky)
|
||||||
|
@ -314,7 +396,7 @@ namespace BizHawk.Client.Common
|
||||||
private List<string> _justPressed = new List<string>();
|
private List<string> _justPressed = new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AutoFireStickyXorAdapter : IController
|
public class AutoFireStickyXorAdapter : IController, ISticky
|
||||||
{
|
{
|
||||||
public int On { get; set; }
|
public int On { get; set; }
|
||||||
public int Off { get; set; }
|
public int Off { get; set; }
|
||||||
|
@ -340,22 +422,7 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
public bool IsPressed(string button)
|
public bool IsPressed(string button)
|
||||||
{
|
{
|
||||||
if (_stickySet.Contains(button))
|
return this[button];
|
||||||
{
|
|
||||||
var a = (Global.Emulator.Frame - buttonStarts[button]) % (On + Off);
|
|
||||||
if (a < On)
|
|
||||||
{
|
|
||||||
return this[button];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Source[button];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool this[string button]
|
public bool this[string button]
|
||||||
|
@ -369,14 +436,14 @@ namespace BizHawk.Client.Common
|
||||||
var a = (Global.Emulator.Frame - buttonStarts[button]) % (On + Off);
|
var a = (Global.Emulator.Frame - buttonStarts[button]) % (On + Off);
|
||||||
if (a < On)
|
if (a < On)
|
||||||
{
|
{
|
||||||
source ^= true;
|
return source ^= true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
source ^= false;
|
return source ^= false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,6 +509,20 @@ namespace BizHawk.Client.Common
|
||||||
_justPressed = buttons;
|
_justPressed = buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines if a sticky is current mashing the button itself,
|
||||||
|
/// If sticky is not set then false, if set, it returns true if the Source is not pressed, else false
|
||||||
|
/// </summary>
|
||||||
|
public bool StickyIsInEffect(string button)
|
||||||
|
{
|
||||||
|
if (Source.IsPressed(button))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (IsPressed(button)); // Shortcut logic since we know the Source isn't pressed, Ispressed can only return true if the autofire sticky is in effect for this frame
|
||||||
|
}
|
||||||
|
|
||||||
private List<string> _justPressed = new List<string>();
|
private List<string> _justPressed = new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -221,21 +221,82 @@ namespace BizHawk.Client.EmuHawk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string InputStrMovie()
|
||||||
public string MakeInputDisplay()
|
|
||||||
{
|
{
|
||||||
StringBuilder sb;
|
var sb = new StringBuilder(Global.GetOutputControllersAsMnemonic());
|
||||||
if (!Global.MovieSession.Movie.IsActive || Global.MovieSession.Movie.IsFinished)
|
|
||||||
{
|
|
||||||
sb = new StringBuilder(Global.GetOutputControllersAsMnemonic());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb = new StringBuilder(Global.MovieSession.Movie.GetInput(Global.Emulator.Frame - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.Replace(".", " ").Replace("|", "").Replace(" 000, 000", " ");
|
sb.Replace(".", " ").Replace("|", "").Replace(" 000, 000", " ");
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string InputStrImmediate()
|
||||||
|
{
|
||||||
|
var mg = new MnemonicsGenerator();
|
||||||
|
mg.SetSource(Global.AutofireStickyXORAdapter);
|
||||||
|
|
||||||
|
var sb = new StringBuilder(mg.GetControllersAsMnemonic());
|
||||||
|
sb.Replace(".", " ").Replace("|", "").Replace(" 000, 000", " ");
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string InputPrevious()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder(Global.MovieSession.Movie.GetInput(Global.Emulator.Frame - 1));
|
||||||
|
sb.Replace(".", " ").Replace("|", "").Replace(" 000, 000", " ");
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string InputStrOrAll()
|
||||||
|
{
|
||||||
|
var m = new MovieControllerAdapter { Type = Global.MovieSession.MovieControllerAdapter.Type };
|
||||||
|
m.SetControllersAsMnemonic(
|
||||||
|
Global.MovieSession.Movie.GetInput(Global.Emulator.Frame - 1));
|
||||||
|
|
||||||
|
var orAdaptor = new ORAdapter()
|
||||||
|
{
|
||||||
|
Source = Global.AutofireStickyXORAdapter,
|
||||||
|
SourceOr = m
|
||||||
|
};
|
||||||
|
|
||||||
|
var mg = new MnemonicsGenerator();
|
||||||
|
mg.SetSource(orAdaptor);
|
||||||
|
|
||||||
|
var sb = new StringBuilder(mg.GetControllersAsMnemonic());
|
||||||
|
sb.Replace(".", " ").Replace("|", "").Replace(" 000, 000", " ");
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string InputStrSticky()
|
||||||
|
{
|
||||||
|
var stickyOr = new StickyOrAdapter
|
||||||
|
{
|
||||||
|
Source = Global.StickyXORAdapter,
|
||||||
|
SourceStickyOr = Global.AutofireStickyXORAdapter
|
||||||
|
};
|
||||||
|
|
||||||
|
var mg = new MnemonicsGenerator();
|
||||||
|
mg.SetSource(stickyOr);
|
||||||
|
var sb = new StringBuilder(mg.GetControllersAsMnemonic());
|
||||||
|
sb.Replace(".", " ").Replace("|", "").Replace(" 000, 000", " ");
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string MakeIntersectImmediatePrevious()
|
||||||
|
{
|
||||||
|
var m = new MovieControllerAdapter { Type = Global.MovieSession.MovieControllerAdapter.Type };
|
||||||
|
m.SetControllersAsMnemonic(
|
||||||
|
Global.MovieSession.Movie.GetInput(Global.Emulator.Frame - 1));
|
||||||
|
|
||||||
|
var andAdaptor = new AndAdapter
|
||||||
|
{
|
||||||
|
Source = Global.AutofireStickyXORAdapter,
|
||||||
|
SourceAnd = m
|
||||||
|
};
|
||||||
|
|
||||||
|
var mg = new MnemonicsGenerator();
|
||||||
|
mg.SetSource(andAdaptor);
|
||||||
|
|
||||||
|
var sb = new StringBuilder(mg.GetControllersAsMnemonic());
|
||||||
|
sb.Replace(".", " ").Replace("|", "").Replace(" 000, 000", " ");
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,10 +306,8 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
return "Rerecord Count: " + Global.MovieSession.Movie.Header.Rerecords;
|
return "Rerecord Count: " + Global.MovieSession.Movie.Header.Rerecords;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
return string.Empty;
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawOsdMessage(IBlitter g, string message, Color color, float x, float y)
|
private void DrawOsdMessage(IBlitter g, string message, Color color, float x, float y)
|
||||||
|
@ -273,22 +332,41 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
if (Global.Config.DisplayInput)
|
if (Global.Config.DisplayInput)
|
||||||
{
|
{
|
||||||
string input = MakeInputDisplay();
|
if (Global.MovieSession.Movie.IsPlaying && !Global.MovieSession.Movie.IsFinished)
|
||||||
Color c;
|
|
||||||
float x = GetX(g, Global.Config.DispInpx, Global.Config.DispInpanchor, input);
|
|
||||||
float y = GetY(g, Global.Config.DispInpy, Global.Config.DispInpanchor, input);
|
|
||||||
if (Global.MovieSession.Movie.IsPlaying && !Global.MovieSession.Movie.IsRecording)
|
|
||||||
{
|
{
|
||||||
c = Color.FromArgb(Global.Config.MovieInput);
|
var input = InputStrMovie();
|
||||||
}
|
var x = GetX(g, Global.Config.DispInpx, Global.Config.DispInpanchor, input);
|
||||||
else
|
var y = GetY(g, Global.Config.DispInpy, Global.Config.DispInpanchor, input);
|
||||||
{
|
Color c = Color.FromArgb(Global.Config.MovieInput);
|
||||||
c = Color.FromArgb(Global.Config.MessagesColor);
|
g.DrawString(input, MessageFont, Color.Black, x + 1, y + 1);
|
||||||
|
g.DrawString(input, MessageFont, c, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this needs to be multi-colored and more intelligent: https://code.google.com/p/bizhawk/issues/detail?id=52
|
else // TODO: message config -- allow setting of "previous", "mixed", and "auto"
|
||||||
g.DrawString(input, MessageFont, Color.Black, x + 1, y + 1);
|
{
|
||||||
g.DrawString(input, MessageFont, c, x, y);
|
var bgStr = InputStrOrAll();
|
||||||
|
var x = GetX(g, Global.Config.DispInpx, Global.Config.DispInpanchor, bgStr);
|
||||||
|
var y = GetY(g, Global.Config.DispInpy, Global.Config.DispInpanchor, bgStr);
|
||||||
|
g.DrawString(bgStr, MessageFont, Color.Black, x + 1, y + 1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var previousStr = InputPrevious();
|
||||||
|
var pColor = Color.Orange;
|
||||||
|
g.DrawString(previousStr, MessageFont, pColor, x, y);
|
||||||
|
|
||||||
|
|
||||||
|
var immediate = InputStrImmediate();
|
||||||
|
Color immediateColor = Color.FromArgb(Global.Config.MessagesColor);
|
||||||
|
g.DrawString(immediate, MessageFont, immediateColor, x, y);
|
||||||
|
|
||||||
|
var immediateOverlay = MakeIntersectImmediatePrevious();
|
||||||
|
var oColor = Color.PeachPuff;
|
||||||
|
g.DrawString(immediateOverlay, MessageFont, oColor, x, y);
|
||||||
|
|
||||||
|
var autoString = InputStrSticky();
|
||||||
|
g.DrawString(autoString, MessageFont, Color.Pink, x, y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Global.MovieSession.MultiTrack.IsActive)
|
if (Global.MovieSession.MultiTrack.IsActive)
|
||||||
|
|
|
@ -448,6 +448,11 @@ namespace BizHawk.Client.EmuHawk
|
||||||
GlobalWin.Tools.LuaConsole.ResumeScripts(false);
|
GlobalWin.Tools.LuaConsole.ResumeScripts(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Global.Config.DisplayInput) // Input display wants to update even while paused
|
||||||
|
{
|
||||||
|
GlobalWin.DisplayManager.NeedsToPaint = true;
|
||||||
|
}
|
||||||
|
|
||||||
StepRunLoop_Core();
|
StepRunLoop_Core();
|
||||||
StepRunLoop_Throttle();
|
StepRunLoop_Throttle();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue