diff --git a/src/Input/Input.bf b/src/Input/Input.bf index 85bf824..ca84905 100644 --- a/src/Input/Input.bf +++ b/src/Input/Input.bf @@ -8,12 +8,14 @@ namespace Strawberry { static private bool* keyboard; static private bool[] previousKeyboard; + static private float[] lastKeypressTimes; static private SDL.SDL_GameController*[] gamepads; static private void Init(int gamepadLimit) { keyboard = SDL.GetKeyboardState(null); previousKeyboard = new bool[(int)SDL.Scancode.NUMSCANCODES]; + lastKeypressTimes = new float[(int)SDL.Scancode.NUMSCANCODES]; gamepads = new SDL.SDL_GameController*[gamepadLimit]; for (let i < gamepads.Count) @@ -23,6 +25,7 @@ namespace Strawberry static private void Dispose() { delete previousKeyboard; + delete lastKeypressTimes; delete gamepads; } @@ -35,49 +38,63 @@ namespace Strawberry static public void AfterUpdate() { for (let i < previousKeyboard.Count) + { + if (!previousKeyboard[i] && keyboard[i]) + lastKeypressTimes[i] = Time.Elapsed; previousKeyboard[i] = keyboard[i]; + } } + static public bool Ctrl => KeyCheck(.LCtrl) || KeyCheck(.RCtrl); + static public bool Alt => KeyCheck(.LAlt) || KeyCheck(.RAlt); + static public bool Shift => KeyCheck(.LShift) || KeyCheck(.RShift); + static public bool KeyCheck(SDL.Scancode key) { - if (keyboard == null) - Debug.FatalError("Polling keyboard before Input.Init"); + Debug.Assert(keyboard != null, "Polling keyboard before Input.Init"); return keyboard[(int)key]; } static public bool KeyPressed(SDL.Scancode key) { - if (keyboard == null) - Debug.FatalError("Polling keyboard before Input.Init"); + Debug.Assert(keyboard != null, "Polling keyboard before Input.Init"); return keyboard[(int)key] && !previousKeyboard[(int)key]; } + static public bool KeyPressed(SDL.Scancode key, float repeatDelay, float repeatInterval) + { + Debug.Assert(keyboard != null, "Polling keyboard before Input.Init"); + + let i = (int)key; + if (keyboard[i]) + return !previousKeyboard[i] || Time.OnInterval(repeatInterval, lastKeypressTimes[i] + repeatDelay); + else + return false; + } + static public bool KeyReleased(SDL.Scancode key) { - if (keyboard == null) - Debug.FatalError("Polling keyboard before Input.Init"); + Debug.Assert(keyboard != null, "Polling keyboard before Input.Init"); return !keyboard[(int)key] && previousKeyboard[(int)key]; } static public bool GamepadButtonCheck(int gamepadID, SDL.SDL_GameControllerButton button) { - if (gamepads == null) - Debug.FatalError("Polling gamepad before Input.Init"); - if (gamepadID >= gamepads.Count) - Debug.FatalError("Gamepad index out of range (increase Game.gamepadLimit!"); + Debug.Assert(gamepads != null, "Polling gamepad before Input.Init"); + Debug.Assert(gamepadID < gamepads.Count, "Gamepad index out of range (increase Game.gamepadLimit!"); + Debug.Assert(gamepadID >= 0, "Negative gamepad index!"); return SDL.GameControllerGetButton(gamepads[gamepadID], button) == 1; } static public float GamepadAxisCheck(int gamepadID, SDL.SDL_GameControllerAxis axis) { - if (gamepads == null) - Debug.FatalError("Polling gamepad before Input.Init"); - if (gamepadID >= gamepads.Count) - Debug.FatalError("Gamepad index out of range (increase Game.gamepadLimit!"); + Debug.Assert(gamepads != null, "Polling gamepad before Input.Init"); + Debug.Assert(gamepadID < gamepads.Count, "Gamepad index out of range (increase Game.gamepadLimit!"); + Debug.Assert(gamepadID >= 0, "Negative gamepad index!"); let val = SDL.GameControllerGetAxis(gamepads[gamepadID], axis); if (val == 0) diff --git a/src/Static/Calc.bf b/src/Static/Calc.bf index d9f9e1b..e3c9e02 100644 --- a/src/Static/Calc.bf +++ b/src/Static/Calc.bf @@ -54,6 +54,18 @@ namespace Strawberry return newMin + (newMax - newMin) * ClampedMap(value, oldMin, oldMax); } + [Inline] + static public bool OnInterval(float current, float previous, float interval, float startDelay = 0) + { + return current >= startDelay && (int)((current - startDelay) / interval) != (int)((previous - startDelay) / interval); + } + + [Inline] + static public bool BetweenInterval(float current, float interval, float startDelay = 0) + { + return current >= startDelay && (current - startDelay) % (interval * 2) >= interval; + } + [Inline] static public void Log() { diff --git a/src/Static/Console.bf b/src/Static/Console.bf index b0724c8..b338c86 100644 --- a/src/Static/Console.bf +++ b/src/Static/Console.bf @@ -8,16 +8,19 @@ namespace Strawberry static private bool enabled; static private SDL2.SDLTTF.Font* font; + static private String entry; static public void Init() { enabled = true; font = SDL2.SDLTTF.OpenFont("../../../../Strawberry/src/Content/strawberry-seeds.ttf", 8); + entry = new String(); } static public void Dispose() { SDL2.SDLTTF.CloseFont(font); + delete entry; } static public bool Enabled @@ -39,8 +42,39 @@ namespace Strawberry Open = !Open; if (Open) + RegisterKeypresses(); + } + } + + static private void RegisterKeypresses() + { + for (let i < (int)SDL2.SDL.Scancode.NUMSCANCODES) + { + let key = (SDL2.SDL.Scancode)i; + if (Input.KeyPressed(key, 0.25f, 0.05f)) { - + if (key >= .A && key <= .Z) + { + char8 c = 'a' + (int)(key - .A); + entry.Append(c); + } + else + { + switch (key) + { + case .Space: + entry.Append(' '); + + case .BackSpace: + if (entry.Length > 0) + entry.RemoveFromEnd(1); + + case .Delete: + entry.Clear(); + + default: + } + } } } } @@ -49,11 +83,14 @@ namespace Strawberry { if (enabled && Open) { - Draw.Rect(0, 0, Game.Width, Game.Height, .Black * 0.5f); + Draw.Rect(0, 0, Game.Width, Game.Height, .Black * 0.6f); + Draw.Rect(0, Game.Height - 12, Game.Width, 14, .Black * 0.6f); Text(">", 0, 0, .White); - if (Time.BetweenInterval(0.5f)) - Text("_", 0, 1, .White); + if (entry.Length > 0) + Text(entry, 0, 1, .White); + if (Time.BetweenInterval(0.3f)) + Text("_", 0, entry.Length + 1, .White); } } diff --git a/src/Static/Time.bf b/src/Static/Time.bf index 076210c..5b44d8f 100644 --- a/src/Static/Time.bf +++ b/src/Static/Time.bf @@ -10,14 +10,14 @@ namespace Strawberry static public float RawDelta => (1 / 60f); static public float Delta => RawDelta * Rate; - static public bool OnInterval(float interval, float offset = 0) + static public bool OnInterval(float interval, float startDelay = 0) { - return (int)((Elapsed - offset) / interval) != (int)((PreviousElapsed - offset) / interval); + return Calc.OnInterval(Elapsed, PreviousElapsed, interval, startDelay); } - static public bool BetweenInterval(float interval, float offset = 0) + static public bool BetweenInterval(float interval, float startDelay = 0) { - return (Elapsed - offset) % (interval * 2) >= interval; + return Calc.BetweenInterval(Time.Elapsed, interval, startDelay); } } }