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];
|
||||
}
|
||||
|
||||
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]; }
|
||||
|
||||
// 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>();
|
||||
|
||||
|
@ -216,7 +281,10 @@ namespace BizHawk.Client.Common
|
|||
|
||||
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
|
||||
// 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)
|
||||
{
|
||||
if (isSticky)
|
||||
|
@ -314,7 +396,7 @@ namespace BizHawk.Client.Common
|
|||
private List<string> _justPressed = new List<string>();
|
||||
}
|
||||
|
||||
public class AutoFireStickyXorAdapter : IController
|
||||
public class AutoFireStickyXorAdapter : IController, ISticky
|
||||
{
|
||||
public int On { get; set; }
|
||||
public int Off { get; set; }
|
||||
|
@ -340,22 +422,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
if (_stickySet.Contains(button))
|
||||
{
|
||||
var a = (Global.Emulator.Frame - buttonStarts[button]) % (On + Off);
|
||||
if (a < On)
|
||||
{
|
||||
return this[button];
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Source[button];
|
||||
}
|
||||
return this[button];
|
||||
}
|
||||
|
||||
public bool this[string button]
|
||||
|
@ -369,14 +436,14 @@ namespace BizHawk.Client.Common
|
|||
var a = (Global.Emulator.Frame - buttonStarts[button]) % (On + Off);
|
||||
if (a < On)
|
||||
{
|
||||
source ^= true;
|
||||
return source ^= true;
|
||||
}
|
||||
else
|
||||
{
|
||||
source ^= false;
|
||||
return source ^= false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
|
@ -442,6 +509,20 @@ namespace BizHawk.Client.Common
|
|||
_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>();
|
||||
}
|
||||
|
||||
|
|
|
@ -221,21 +221,82 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public string MakeInputDisplay()
|
||||
public string InputStrMovie()
|
||||
{
|
||||
StringBuilder sb;
|
||||
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));
|
||||
}
|
||||
|
||||
var sb = new StringBuilder(Global.GetOutputControllersAsMnemonic());
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -245,10 +306,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
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)
|
||||
|
@ -273,22 +332,41 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
if (Global.Config.DisplayInput)
|
||||
{
|
||||
string input = MakeInputDisplay();
|
||||
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)
|
||||
if (Global.MovieSession.Movie.IsPlaying && !Global.MovieSession.Movie.IsFinished)
|
||||
{
|
||||
c = Color.FromArgb(Global.Config.MovieInput);
|
||||
}
|
||||
else
|
||||
{
|
||||
c = Color.FromArgb(Global.Config.MessagesColor);
|
||||
var input = InputStrMovie();
|
||||
var x = GetX(g, Global.Config.DispInpx, Global.Config.DispInpanchor, input);
|
||||
var y = GetY(g, Global.Config.DispInpy, Global.Config.DispInpanchor, input);
|
||||
Color c = Color.FromArgb(Global.Config.MovieInput);
|
||||
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
|
||||
g.DrawString(input, MessageFont, Color.Black, x + 1, y + 1);
|
||||
g.DrawString(input, MessageFont, c, x, y);
|
||||
else // TODO: message config -- allow setting of "previous", "mixed", and "auto"
|
||||
{
|
||||
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)
|
||||
|
|
|
@ -448,6 +448,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
GlobalWin.Tools.LuaConsole.ResumeScripts(false);
|
||||
}
|
||||
|
||||
if (Global.Config.DisplayInput) // Input display wants to update even while paused
|
||||
{
|
||||
GlobalWin.DisplayManager.NeedsToPaint = true;
|
||||
}
|
||||
|
||||
StepRunLoop_Core();
|
||||
StepRunLoop_Throttle();
|
||||
|
||||
|
|
Loading…
Reference in New Issue