From ae1b6125242c8ee1088f153247ab9456492ea5cf Mon Sep 17 00:00:00 2001 From: dnesov Date: Fri, 20 Jun 2025 23:02:46 +0200 Subject: [PATCH] Workaround: cache inputs in RaylibInputSystem and force rendering at 60 FPS for more consistent inputs. --- Voile/Source/Game.cs | 7 ++ Voile/Source/Input/InputSystem.cs | 6 ++ Voile/Source/Input/RaylibInputSystem.cs | 104 +++++++++---------- Voile/Source/Rendering/RaylibRenderSystem.cs | 1 + 4 files changed, 66 insertions(+), 52 deletions(-) diff --git a/Voile/Source/Game.cs b/Voile/Source/Game.cs index dc7e601..f550728 100644 --- a/Voile/Source/Game.cs +++ b/Voile/Source/Game.cs @@ -164,6 +164,11 @@ namespace Voile throw new NullReferenceException("No renderer provided."); } + if (Input is null) + { + throw new NullReferenceException("No input system provided."); + } + Stopwatch stopwatch = Stopwatch.StartNew(); double previousTime = stopwatch.Elapsed.TotalSeconds; @@ -175,6 +180,8 @@ namespace Voile _accumulator += elapsedTime; + Input.Poll(); + while (_accumulator >= UpdateTimeStep) { foreach (var system in _updatableSystems) diff --git a/Voile/Source/Input/InputSystem.cs b/Voile/Source/Input/InputSystem.cs index 5168603..87ccce6 100644 --- a/Voile/Source/Input/InputSystem.cs +++ b/Voile/Source/Input/InputSystem.cs @@ -20,6 +20,12 @@ namespace Voile.Input CreateDefaultMappings(); } + /// + /// Forces this input system to poll all of its inputs during current frame.
+ /// Some backends require inputs to be polled once per specific interval. Override this method to implement this behavior. + ///
+ public virtual void Poll() { } + public void Shutdown() => Dispose(); public void Dispose() => GC.SuppressFinalize(this); diff --git a/Voile/Source/Input/RaylibInputSystem.cs b/Voile/Source/Input/RaylibInputSystem.cs index 1391c40..58aa7e3 100644 --- a/Voile/Source/Input/RaylibInputSystem.cs +++ b/Voile/Source/Input/RaylibInputSystem.cs @@ -8,63 +8,63 @@ namespace Voile.Input /// public class RaylibInputSystem : InputSystem { - public override int GetCharPressed() + public override void Poll() { - return Raylib.GetCharPressed(); + _justPressedKeys.Clear(); + _justReleasedKeys.Clear(); + _downKeys.Clear(); + + _pressedMouseButtons.Clear(); + _releasedMouseButtons.Clear(); + _downMouseButtons.Clear(); + + for (int key = 32; key <= 349; key++) + { + var k = (KeyboardKey)key; + if (Raylib.IsKeyPressed((Raylib_cs.KeyboardKey)k)) _justPressedKeys.Add(k); + if (Raylib.IsKeyReleased((Raylib_cs.KeyboardKey)k)) _justReleasedKeys.Add(k); + if (Raylib.IsKeyDown((Raylib_cs.KeyboardKey)k)) _downKeys.Add(k); + } + + foreach (MouseButton button in System.Enum.GetValues(typeof(MouseButton))) + { + var rayButton = (Raylib_cs.MouseButton)button; + if (Raylib.IsMouseButtonPressed(rayButton)) _pressedMouseButtons.Add(button); + if (Raylib.IsMouseButtonReleased(rayButton)) _releasedMouseButtons.Add(button); + if (Raylib.IsMouseButtonDown(rayButton)) _downMouseButtons.Add(button); + } + + _mousePosition = Raylib.GetMousePosition(); + _mouseWheelMove = Raylib.GetMouseWheelMove(); } - public override Vector2 GetMousePosition() - { - return Raylib.GetMousePosition(); - } + public override int GetCharPressed() => Raylib.GetCharPressed(); + public override Vector2 GetMousePosition() => _mousePosition; + public override float GetMouseWheelMovement() => _mouseWheelMove; - public override float GetMouseWheelMovement() - { - return Raylib.GetMouseWheelMove(); - } - - public override void HideCursor() - { - Raylib.HideCursor(); - } - - public override bool IsKeyboardKeyDown(KeyboardKey key) - { - Raylib_cs.KeyboardKey rayKey = (Raylib_cs.KeyboardKey)key; - return Raylib.IsKeyDown(rayKey); - } - - public override bool IsMousePressed(MouseButton button) - { - return Raylib.IsMouseButtonPressed((Raylib_cs.MouseButton)button); - } - - public override bool IsMouseButtonReleased(MouseButton button) - { - return Raylib.IsMouseButtonReleased((Raylib_cs.MouseButton)button); - } - - public override bool IsMouseButtonDown(MouseButton button) - { - return Raylib.IsMouseButtonDown((Raylib_cs.MouseButton)button); - } - - public override bool KeyboardKeyJustPressed(KeyboardKey key) - { - Raylib_cs.KeyboardKey rayKey = (Raylib_cs.KeyboardKey)key; - return Raylib.IsKeyPressed(rayKey); - } - - public override bool KeyboardKeyJustReleased(KeyboardKey key) - { - return Raylib.IsKeyReleased((Raylib_cs.KeyboardKey)key); - } - - public override void SetMousePosition(Vector2 position) - { - Raylib.SetMousePosition((int)position.X, (int)position.Y); - } + public override void HideCursor() => Raylib.HideCursor(); public override void ShowCursor() => Raylib.ShowCursor(); public override bool IsCursorHidden() => Raylib.IsCursorHidden(); + + public override bool IsKeyboardKeyDown(KeyboardKey key) => _downKeys.Contains(key); + public override bool KeyboardKeyJustPressed(KeyboardKey key) => _justPressedKeys.Contains(key); + public override bool KeyboardKeyJustReleased(KeyboardKey key) => _justReleasedKeys.Contains(key); + + public override bool IsMousePressed(MouseButton button) => _pressedMouseButtons.Contains(button); + public override bool IsMouseButtonReleased(MouseButton button) => _releasedMouseButtons.Contains(button); + public override bool IsMouseButtonDown(MouseButton button) => _downMouseButtons.Contains(button); + + public override void SetMousePosition(Vector2 position) => Raylib.SetMousePosition((int)position.X, (int)position.Y); + + private readonly HashSet _justPressedKeys = new(); + private readonly HashSet _justReleasedKeys = new(); + private readonly HashSet _downKeys = new(); + + private readonly HashSet _pressedMouseButtons = new(); + private readonly HashSet _releasedMouseButtons = new(); + private readonly HashSet _downMouseButtons = new(); + + private Vector2 _mousePosition; + private float _mouseWheelMove; } } \ No newline at end of file diff --git a/Voile/Source/Rendering/RaylibRenderSystem.cs b/Voile/Source/Rendering/RaylibRenderSystem.cs index 83a287d..503c11f 100644 --- a/Voile/Source/Rendering/RaylibRenderSystem.cs +++ b/Voile/Source/Rendering/RaylibRenderSystem.cs @@ -49,6 +49,7 @@ namespace Voile.Rendering _defaultFlags = flags; Raylib.SetConfigFlags(flags); + Raylib.SetTargetFPS(settings.TargetFps); } public override void CreateAndInitializeWithWindow(RendererSettings settings)