From b3f82a148ac59ae0615597e553fb64b836616d63 Mon Sep 17 00:00:00 2001 From: "actondev (Christos)" Date: Sun, 20 Aug 2023 23:53:20 +0200 Subject: [PATCH] Add `IsKeyPressedRepeat` (desktop only) (#3245) Since the key pressed are handle by comparing current vs previous state (ie frame), a special way is needed to handle key repeats. --- src/raylib.h | 1 + src/rcore.c | 26 +++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index abc8371b..d932e3a3 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1115,6 +1115,7 @@ RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize // Input-related functions: keyboard RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once +RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again (Only PLATFORM_DESKTOP) RLAPI bool IsKeyDown(int key); // Check if a key is being pressed RLAPI bool IsKeyReleased(int key); // Check if a key has been released once RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed diff --git a/src/rcore.c b/src/rcore.c index 7d8811b0..52a58d6d 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -438,6 +438,8 @@ typedef struct CoreData { int exitKey; // Default exit key char currentKeyState[MAX_KEYBOARD_KEYS]; // Registers current frame key state char previousKeyState[MAX_KEYBOARD_KEYS]; // Registers previous frame key state + // NOTE: Since key press logic involves comparing prev vs cur key state, we need to handle key repeats specially + char keyRepeatInFrame[MAX_KEYBOARD_KEYS]; // Registers key repeats for current frame. int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]; // Input keys queue int keyPressedQueueCount; // Input keys queue count @@ -3755,6 +3757,13 @@ bool IsKeyPressed(int key) return pressed; } +// Check if a key has been pressed again (only PLATFORM_DESKTOP) +bool IsKeyPressedRepeat(int key) +{ + if (CORE.Input.Keyboard.keyRepeatInFrame[key] == 1) return true; + else return true; +} + // Check if a key is being pressed (key held down) bool IsKeyDown(int key) { @@ -5170,6 +5179,8 @@ void PollInputEvents(void) // Reset keys/chars pressed registered CORE.Input.Keyboard.keyPressedQueueCount = 0; CORE.Input.Keyboard.charPressedQueueCount = 0; + // Reset key repeats + for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.keyRepeatInFrame[i] = 0; #if !(defined(PLATFORM_RPI) || defined(PLATFORM_DRM)) // Reset last gamepad button/axis registered state @@ -5179,7 +5190,11 @@ void PollInputEvents(void) #if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) // Register previous keys states - for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i]; + for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) + { + CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i]; + CORE.Input.Keyboard.keyRepeatInFrame[i] = 0; + } PollKeyboardEvents(); @@ -5586,7 +5601,8 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i // WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1 // to work properly with our implementation (IsKeyDown/IsKeyUp checks) if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0; - else CORE.Input.Keyboard.currentKeyState[key] = 1; + else if(action == GLFW_PRESS) CORE.Input.Keyboard.currentKeyState[key] = 1; + else if(action == GLFW_REPEAT) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1; #if !defined(PLATFORM_WEB) // WARNING: Check if CAPS/NUM key modifiers are enabled and force down state for those keys @@ -6357,7 +6373,11 @@ static void ProcessKeyboard(void) bufferByteCount = read(STDIN_FILENO, keysBuffer, MAX_KEYBUFFER_SIZE); // POSIX system call // Reset pressed keys array (it will be filled below) - for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.currentKeyState[i] = 0; + for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) + { + CORE.Input.Keyboard.currentKeyState[i] = 0; + CORE.Input.Keyboard.keyRepeatInFrame[i] = 0; + } // Fill all read bytes (looking for keys) for (int i = 0; i < bufferByteCount; i++)