From a814bab0d62ab17bb7662473bc97674d3cadac20 Mon Sep 17 00:00:00 2001 From: Evan Hemsley Date: Thu, 28 Dec 2023 09:12:37 -0800 Subject: [PATCH] Use SDL_GetKeyboardState instead of event polling --- src/FNAPlatform/FNAPlatform.cs | 4 ++ src/FNAPlatform/SDL2_FNAPlatform.cs | 95 +++++++++++++++++++++++------ src/Input/Keyboard.cs | 10 +-- 3 files changed, 87 insertions(+), 22 deletions(-) diff --git a/src/FNAPlatform/FNAPlatform.cs b/src/FNAPlatform/FNAPlatform.cs index 100175c28..6ffb61e95 100644 --- a/src/FNAPlatform/FNAPlatform.cs +++ b/src/FNAPlatform/FNAPlatform.cs @@ -111,6 +111,7 @@ static FNAPlatform() PollEvents = SDL2_FNAPlatform.PollEvents; GetGraphicsAdapters = SDL2_FNAPlatform.GetGraphicsAdapters; GetCurrentDisplayMode = SDL2_FNAPlatform.GetCurrentDisplayMode; + GetKeyboardState = SDL2_FNAPlatform.GetKeyboardState; GetKeyFromScancode = SDL2_FNAPlatform.GetKeyFromScancode; IsTextInputActive = SDL2_FNAPlatform.IsTextInputActive; StartTextInput = SDL2.SDL.SDL_StartTextInput; @@ -261,6 +262,9 @@ ref bool textInputSuppress public delegate DisplayMode GetCurrentDisplayModeFunc(int adapterIndex); public static readonly GetCurrentDisplayModeFunc GetCurrentDisplayMode; + public delegate void GetKeyboardStateFunc(List activeKeys); + public static readonly GetKeyboardStateFunc GetKeyboardState; + public delegate Keys GetKeyFromScancodeFunc(Keys scancode); public static readonly GetKeyFromScancodeFunc GetKeyFromScancode; diff --git a/src/FNAPlatform/SDL2_FNAPlatform.cs b/src/FNAPlatform/SDL2_FNAPlatform.cs index 5d7c8be95..8688f6c53 100644 --- a/src/FNAPlatform/SDL2_FNAPlatform.cs +++ b/src/FNAPlatform/SDL2_FNAPlatform.cs @@ -45,6 +45,14 @@ internal static class SDL2_FNAPlatform #endregion + #region Keyboard State + + // Used for special copy-paste text input + private static bool LeftControlDown = false; + private static bool RightControlDown = false; + + #endregion + #region Init/Exit Methods public static string ProgramInit(LaunchParameters args) @@ -954,16 +962,24 @@ ref bool textInputSuppress if (evt.type == SDL.SDL_EventType.SDL_KEYDOWN) { Keys key = ToXNAKey(ref evt.key.keysym); - if (!Keyboard.keys.Contains(key)) + if (key == Keys.LeftControl) + { + LeftControlDown = true; + } + else if (key == Keys.RightControl) + { + RightControlDown = true; + } + + if (evt.key.repeat == 0) { - Keyboard.keys.Add(key); int textIndex; if (FNAPlatform.TextInputBindings.TryGetValue(key, out textIndex)) { textInputControlDown[textIndex] = true; TextInputEXT.OnTextInput(FNAPlatform.TextInputCharacters[textIndex]); } - else if ((Keyboard.keys.Contains(Keys.LeftControl) || Keyboard.keys.Contains(Keys.RightControl)) + else if ((LeftControlDown || RightControlDown) && key == Keys.V) { textInputControlDown[6] = true; @@ -971,14 +987,14 @@ ref bool textInputSuppress textInputSuppress = true; } } - else if (evt.key.repeat > 0) + else { int textIndex; if (FNAPlatform.TextInputBindings.TryGetValue(key, out textIndex)) { TextInputEXT.OnTextInput(FNAPlatform.TextInputCharacters[textIndex]); } - else if ((Keyboard.keys.Contains(Keys.LeftControl) || Keyboard.keys.Contains(Keys.RightControl)) + else if ((LeftControlDown || RightControlDown) && key == Keys.V) { TextInputEXT.OnTextInput(FNAPlatform.TextInputCharacters[6]); @@ -988,19 +1004,26 @@ ref bool textInputSuppress else if (evt.type == SDL.SDL_EventType.SDL_KEYUP) { Keys key = ToXNAKey(ref evt.key.keysym); - if (Keyboard.keys.Remove(key)) + + if (key == Keys.LeftControl) { - int value; - if (FNAPlatform.TextInputBindings.TryGetValue(key, out value)) - { - textInputControlDown[value] = false; - } - else if (((!Keyboard.keys.Contains(Keys.LeftControl) && !Keyboard.keys.Contains(Keys.RightControl)) && textInputControlDown[6]) - || key == Keys.V) - { - textInputControlDown[6] = false; - textInputSuppress = false; - } + LeftControlDown = false; + } + else if (key == Keys.RightControl) + { + RightControlDown = false; + } + + int value; + if (FNAPlatform.TextInputBindings.TryGetValue(key, out value)) + { + textInputControlDown[value] = false; + } + else if (((!LeftControlDown && !RightControlDown) && textInputControlDown[6]) + || key == Keys.V) + { + textInputControlDown[6] = false; + textInputSuppress = false; } } @@ -1215,7 +1238,7 @@ ref bool textInputSuppress } } - else if (evt.type == SDL.SDL_EventType.SDL_TEXTEDITING) + else if (evt.type == SDL.SDL_EventType.SDL_TEXTEDITING) { int bytes = MeasureStringLength(evt.edit.text); if (bytes > 0) @@ -2843,6 +2866,42 @@ public static Keys GetKeyFromScancode(Keys scancode) return Keys.None; } + public static unsafe void GetKeyboardState(List activeKeys) + { + int numkeys; + byte* state = (byte*) SDL.SDL_GetKeyboardState(out numkeys); + if (UseScancodes) + { + for (int i = 0; i < numkeys; i += 1) + { + if (state[i] != 0) + { + Keys key; + if (INTERNAL_scanMap.TryGetValue(i, out key)) + { + activeKeys.Add(key); + } + } + } + } + else + { + for (int i = 0; i < numkeys; i += 1) + { + if (state[i] != 0) + { + Keys key; + if (INTERNAL_keyMap.TryGetValue( + (int) SDL.SDL_GetKeyFromScancode((SDL.SDL_Scancode) i), + out key + )) { + activeKeys.Add(key); + } + } + } + } + } + #endregion #region Private Static Win32 WM_PAINT Interop diff --git a/src/Input/Keyboard.cs b/src/Input/Keyboard.cs index 61f1090ac..1d0bf3588 100644 --- a/src/Input/Keyboard.cs +++ b/src/Input/Keyboard.cs @@ -27,7 +27,9 @@ public static class Keyboard /// Current keyboard state. public static KeyboardState GetState() { - return new KeyboardState(keys); + activeKeys.Clear(); + FNAPlatform.GetKeyboardState(activeKeys); + return new KeyboardState(activeKeys); } /// @@ -37,7 +39,7 @@ public static KeyboardState GetState() /// Current keyboard state. public static KeyboardState GetState(PlayerIndex playerIndex) { - return new KeyboardState(keys); + return GetState(); } #endregion @@ -51,9 +53,9 @@ public static Keys GetKeyFromScancodeEXT(Keys scancode) #endregion - #region Internal Static Variables + #region Private Static Variables - internal static List keys = new List(); + private static List activeKeys = new List(); #endregion }