Basic key repeat functionality

This commit is contained in:
Owen Grenney 2022-08-01 20:10:31 +01:00
parent 85bd13c41d
commit 644ac11941
4 changed files with 78 additions and 35 deletions

View File

@ -2,7 +2,7 @@
* *
* raylib [text] example - Input Box * raylib [text] example - Input Box
* *
* Example originally created with raylib 1.7, last time updated with raylib 3.5 * Example originally created with raylib 1.7, last time updated with raylib 4.0
* *
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
@ -35,7 +35,7 @@ int main(void)
int framesCounter = 0; int framesCounter = 0;
SetTargetFPS(10); // Set our game to run at 10 frames-per-second SetTargetFPS(30); // Set our game to run at 30 frames-per-second
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// Main game loop // Main game loop
@ -68,7 +68,7 @@ int main(void)
key = GetCharPressed(); // Check next character in the queue key = GetCharPressed(); // Check next character in the queue
} }
if (IsKeyPressed(KEY_BACKSPACE)) if (IsKeyRepeated(KEY_BACKSPACE))
{ {
letterCount--; letterCount--;
if (letterCount < 0) letterCount = 0; if (letterCount < 0) letterCount = 0;
@ -118,15 +118,3 @@ int main(void)
return 0; return 0;
} }
// Check if any key is pressed
// NOTE: We limit keys check to keys between 32 (KEY_SPACE) and 126
bool IsAnyKeyPressed()
{
bool keyPressed = false;
int key = GetKeyPressed();
if ((key >= 32) && (key <= 126)) keyPressed = true;
return keyPressed;
}

View File

@ -83,6 +83,7 @@
#define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported #define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported
#define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue #define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue
#define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue #define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue
#define MAX_KEY_REPEATED_QUEUE 16 // Maximum number of keys in the key repeat queue
#define MAX_DECOMPRESSION_SIZE 64 // Max size allocated for decompression in MB #define MAX_DECOMPRESSION_SIZE 64 // Max size allocated for decompression in MB

View File

@ -1096,9 +1096,11 @@ RLAPI bool IsKeyPressed(int key); // Check if a key
RLAPI bool IsKeyDown(int key); // Check if a key is being pressed 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 IsKeyReleased(int key); // Check if a key has been released once
RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed
RLAPI bool IsKeyRepeated(int key); // Check if a key has been repeated
RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC) RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
RLAPI int GetKeyPressed(void); // Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty RLAPI int GetKeyPressed(void); // Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty
RLAPI int GetCharPressed(void); // Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty RLAPI int GetCharPressed(void); // Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty
RLAPI int GetKeyRepeated(void); // Get key pressed (keycode) with repeat rate, call it multiple times for keys queued, returns 0 when the queue is empty
// Input-related functions: gamepads // Input-related functions: gamepads
RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available

View File

@ -424,6 +424,7 @@ typedef struct CoreData {
int exitKey; // Default exit key int exitKey; // Default exit key
char currentKeyState[MAX_KEYBOARD_KEYS]; // Registers current frame key state char currentKeyState[MAX_KEYBOARD_KEYS]; // Registers current frame key state
char previousKeyState[MAX_KEYBOARD_KEYS]; // Registers previous frame key state char previousKeyState[MAX_KEYBOARD_KEYS]; // Registers previous frame key state
char repeatedKeyState[MAX_KEYBOARD_KEYS]; // Registers repeated key state
int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]; // Input keys queue int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]; // Input keys queue
int keyPressedQueueCount; // Input keys queue count int keyPressedQueueCount; // Input keys queue count
@ -431,6 +432,9 @@ typedef struct CoreData {
int charPressedQueue[MAX_CHAR_PRESSED_QUEUE]; // Input characters queue (unicode) int charPressedQueue[MAX_CHAR_PRESSED_QUEUE]; // Input characters queue (unicode)
int charPressedQueueCount; // Input characters queue count int charPressedQueueCount; // Input characters queue count
int keyRepeatedQueue[MAX_KEY_REPEATED_QUEUE]; // Input keys repeated queue
int keyRepeatedQueueCount; // Input keys repeated queue count
#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) #if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
int defaultMode; // Default keyboard mode int defaultMode; // Default keyboard mode
#if defined(SUPPORT_SSH_KEYBOARD_RPI) #if defined(SUPPORT_SSH_KEYBOARD_RPI)
@ -3485,6 +3489,16 @@ bool IsKeyUp(int key)
else return false; else return false;
} }
// Check if a key has been repeated
bool IsKeyRepeated(int key)
{
bool repeated = false;
if (CORE.Input.Keyboard.repeatedKeyState[key] == 1) repeated = true;
return repeated;
}
// Get the last key pressed // Get the last key pressed
int GetKeyPressed(void) int GetKeyPressed(void)
{ {
@ -3529,6 +3543,28 @@ int GetCharPressed(void)
return value; return value;
} }
// Get the last key pressed with repeat rate
int GetKeyRepeated(void)
{
int value = 0;
if (CORE.Input.Keyboard.keyRepeatedQueueCount > 0)
{
// Get character from the queue head
value = CORE.Input.Keyboard.keyRepeatedQueue[0];
// Shift elements 1 step toward the head.
for (int i = 0; i < (CORE.Input.Keyboard.keyRepeatedQueueCount - 1); i++)
CORE.Input.Keyboard.keyRepeatedQueue[i] = CORE.Input.Keyboard.keyRepeatedQueue[i + 1];
// Reset last character in the queue
CORE.Input.Keyboard.keyRepeatedQueue[CORE.Input.Keyboard.keyRepeatedQueueCount] = 0;
CORE.Input.Keyboard.keyRepeatedQueueCount--;
}
return value;
}
// Set a custom key to exit program // Set a custom key to exit program
// NOTE: default exitKey is ESCAPE // NOTE: default exitKey is ESCAPE
void SetExitKey(int key) void SetExitKey(int key)
@ -4920,6 +4956,10 @@ void PollInputEvents(void)
// Register previous mouse states // Register previous mouse states
for (int i = 0; i < MAX_MOUSE_BUTTONS; i++) CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i]; for (int i = 0; i < MAX_MOUSE_BUTTONS; i++) CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
// Clear previous repeated keys
// for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.repeatedKeyState[i] = 0;
memset(CORE.Input.Keyboard.repeatedKeyState, 0, MAX_KEYBOARD_KEYS * (sizeof(char)));
// Register previous mouse wheel state // Register previous mouse wheel state
CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove; CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove;
CORE.Input.Mouse.currentWheelMove = (Vector2){ 0.0f, 0.0f }; CORE.Input.Mouse.currentWheelMove = (Vector2){ 0.0f, 0.0f };
@ -5294,6 +5334,10 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0; if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0;
else CORE.Input.Keyboard.currentKeyState[key] = 1; else CORE.Input.Keyboard.currentKeyState[key] = 1;
// Same thing here: GLFW could return GLFW_PRESS, which is the initial
// key press that starts the repeat
if (action != GLFW_RELEASE) CORE.Input.Keyboard.repeatedKeyState[key] = 1;
// Check if there is space available in the key queue // Check if there is space available in the key queue
if ((CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE) && (action == GLFW_PRESS)) if ((CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE) && (action == GLFW_PRESS))
{ {
@ -5302,6 +5346,14 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
CORE.Input.Keyboard.keyPressedQueueCount++; CORE.Input.Keyboard.keyPressedQueueCount++;
} }
// Check if there is space available in the repeated key queue
if ((CORE.Input.Keyboard.keyRepeatedQueueCount < MAX_KEY_REPEATED_QUEUE) && (action == GLFW_REPEAT || action == GLFW_PRESS))
{
// Add character to the queue
CORE.Input.Keyboard.keyRepeatedQueue[CORE.Input.Keyboard.keyRepeatedQueueCount] = key;
CORE.Input.Keyboard.keyRepeatedQueueCount++;
}
// Check the exit key to set close window // Check the exit key to set close window
if ((key == CORE.Input.Keyboard.exitKey) && (action == GLFW_PRESS)) glfwSetWindowShouldClose(CORE.Window.handle, GLFW_TRUE); if ((key == CORE.Input.Keyboard.exitKey) && (action == GLFW_PRESS)) glfwSetWindowShouldClose(CORE.Window.handle, GLFW_TRUE);