use buffered mode for keyboard input, so that it is impossible for quick keystrokes to get missed. also increase priority of input thread.
This commit is contained in:
parent
06ffa9601c
commit
39ec2ebc90
|
@ -92,7 +92,11 @@ namespace BizHawk.Client.EmuHawk
|
||||||
private Input()
|
private Input()
|
||||||
{
|
{
|
||||||
#if WINDOWS
|
#if WINDOWS
|
||||||
UpdateThread = new Thread(UpdateThreadProc) {IsBackground = true};
|
UpdateThread = new Thread(UpdateThreadProc)
|
||||||
|
{
|
||||||
|
IsBackground = true,
|
||||||
|
Priority = ThreadPriority.AboveNormal //why not? this thread shouldn't be very heavy duty, and we want it to be responsive
|
||||||
|
};
|
||||||
UpdateThread.Start();
|
UpdateThread.Start();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -172,7 +176,8 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
void HandleButton(string button, bool newState)
|
void HandleButton(string button, bool newState)
|
||||||
{
|
{
|
||||||
if (EnableIgnoreModifiers && IgnoreKeys.Contains(button)) return;
|
bool isModifier = IgnoreKeys.Contains(button);
|
||||||
|
if (EnableIgnoreModifiers && isModifier) return;
|
||||||
if (LastState[button] && newState) return;
|
if (LastState[button] && newState) return;
|
||||||
if (!LastState[button] && !newState) return;
|
if (!LastState[button] && !newState) return;
|
||||||
|
|
||||||
|
@ -185,6 +190,15 @@ namespace BizHawk.Client.EmuHawk
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//apply
|
||||||
|
//NOTE: this is not quite right. if someone held leftshift+rightshift it would be broken. seems unlikely, though.
|
||||||
|
if (button == "LeftShift") { _Modifiers &= ~ModifierKey.Shift; if (newState) _Modifiers |= ModifierKey.Shift; }
|
||||||
|
if (button == "RightShift") { _Modifiers &= ~ModifierKey.Shift; if (newState) _Modifiers |= ModifierKey.Shift; }
|
||||||
|
if (button == "LeftControl"){ _Modifiers &= ~ModifierKey.Control; if (newState) _Modifiers |= ModifierKey.Control; }
|
||||||
|
if (button == "RightControl"){ _Modifiers &= ~ModifierKey.Control; if (newState) _Modifiers |= ModifierKey.Control; }
|
||||||
|
if (button == "LeftAlt") { _Modifiers &= ~ModifierKey.Alt; if (newState) _Modifiers |= ModifierKey.Alt; }
|
||||||
|
if (button == "RightAlt") { _Modifiers &= ~ModifierKey.Alt; if (newState) _Modifiers |= ModifierKey.Alt; }
|
||||||
|
|
||||||
//dont generate events for things like Ctrl+LeftControl
|
//dont generate events for things like Ctrl+LeftControl
|
||||||
ModifierKey mods = _Modifiers;
|
ModifierKey mods = _Modifiers;
|
||||||
if (button == "LeftShift") mods &= ~ModifierKey.Shift;
|
if (button == "LeftShift") mods &= ~ModifierKey.Shift;
|
||||||
|
@ -219,7 +233,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
LogicalButton alreadyReleased = ie.LogicalButton;
|
LogicalButton alreadyReleased = ie.LogicalButton;
|
||||||
var ieModified = new InputEvent
|
var ieModified = new InputEvent
|
||||||
{
|
{
|
||||||
LogicalButton = (LogicalButton) ModifierState[button],
|
LogicalButton = (LogicalButton)ModifierState[button],
|
||||||
EventType = InputEventType.Release
|
EventType = InputEventType.Release
|
||||||
};
|
};
|
||||||
if (ieModified.LogicalButton != alreadyReleased)
|
if (ieModified.LogicalButton != alreadyReleased)
|
||||||
|
@ -276,26 +290,18 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
for (; ; )
|
for (; ; )
|
||||||
{
|
{
|
||||||
KeyInput.Update();
|
var keyEvents = KeyInput.Update();
|
||||||
GamePad.UpdateAll();
|
GamePad.UpdateAll();
|
||||||
GamePad360.UpdateAll();
|
GamePad360.UpdateAll();
|
||||||
|
|
||||||
_Modifiers = KeyInput.GetModifierKeysAsKeys();
|
|
||||||
|
|
||||||
//this block is going to massively modify data structures that the binding method uses, so we have to lock it all
|
//this block is going to massively modify data structures that the binding method uses, so we have to lock it all
|
||||||
lock (this)
|
lock (this)
|
||||||
{
|
{
|
||||||
_NewEvents.Clear();
|
_NewEvents.Clear();
|
||||||
|
|
||||||
//analyze keys
|
//analyze keys
|
||||||
var bleh = new HashSet<Key>();
|
foreach (var ke in keyEvents)
|
||||||
foreach (var k in KeyInput.State.PressedKeys)
|
HandleButton(ke.Key.ToString(), ke.Pressed);
|
||||||
bleh.Add(k);
|
|
||||||
foreach (var k in KeyInput.State.AllKeys)
|
|
||||||
if (bleh.Contains(k))
|
|
||||||
HandleButton(k.ToString(), true);
|
|
||||||
else
|
|
||||||
HandleButton(k.ToString(), false);
|
|
||||||
|
|
||||||
lock (FloatValues)
|
lock (FloatValues)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using SlimDX;
|
using System.Collections.Generic;
|
||||||
|
using SlimDX;
|
||||||
using SlimDX.DirectInput;
|
using SlimDX.DirectInput;
|
||||||
|
|
||||||
namespace BizHawk.Client.EmuHawk
|
namespace BizHawk.Client.EmuHawk
|
||||||
|
@ -17,21 +18,45 @@ namespace BizHawk.Client.EmuHawk
|
||||||
if (keyboard == null || keyboard.Disposed)
|
if (keyboard == null || keyboard.Disposed)
|
||||||
keyboard = new Keyboard(dinput);
|
keyboard = new Keyboard(dinput);
|
||||||
keyboard.SetCooperativeLevel(GlobalWin.MainForm.Handle, CooperativeLevel.Background | CooperativeLevel.Nonexclusive);
|
keyboard.SetCooperativeLevel(GlobalWin.MainForm.Handle, CooperativeLevel.Background | CooperativeLevel.Nonexclusive);
|
||||||
|
keyboard.Properties.BufferSize = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Update()
|
static List<KeyEvent> EmptyList = new List<KeyEvent>();
|
||||||
|
static List<KeyEvent> EventList = new List<KeyEvent>();
|
||||||
|
|
||||||
|
public static IEnumerable<KeyEvent> Update()
|
||||||
{
|
{
|
||||||
if (keyboard.Acquire().IsFailure)
|
EventList.Clear();
|
||||||
return;
|
|
||||||
if (keyboard.Poll().IsFailure)
|
|
||||||
return;
|
|
||||||
|
|
||||||
keyboard.GetCurrentState(ref state);
|
if (keyboard.Acquire().IsFailure)
|
||||||
if (Result.Last.IsFailure)
|
return EmptyList;
|
||||||
return;
|
if (keyboard.Poll().IsFailure)
|
||||||
|
return EmptyList;
|
||||||
|
|
||||||
|
for (; ; )
|
||||||
|
{
|
||||||
|
var events = keyboard.GetBufferedData();
|
||||||
|
if (Result.Last.IsFailure)
|
||||||
|
return EventList;
|
||||||
|
if (events.Count == 0)
|
||||||
|
break;
|
||||||
|
foreach (var e in events)
|
||||||
|
{
|
||||||
|
foreach (var k in e.PressedKeys)
|
||||||
|
EventList.Add(new KeyEvent { Key = k, Pressed = true });
|
||||||
|
foreach (var k in e.ReleasedKeys)
|
||||||
|
EventList.Add(new KeyEvent { Key = k, Pressed = false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EventList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static KeyboardState State { get { return state; } }
|
public struct KeyEvent
|
||||||
|
{
|
||||||
|
public Key Key;
|
||||||
|
public bool Pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static bool IsPressed(Key key)
|
public static bool IsPressed(Key key)
|
||||||
|
|
Loading…
Reference in New Issue