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:
adelikat 2014-04-28 00:39:40 +00:00
parent 36c09eea0f
commit c863d57113
4 changed files with 228 additions and 51 deletions

View File

@ -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.

View File

@ -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>();
}

View File

@ -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)

View File

@ -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();