[rcore] Add basic support for scancodes#4481
Conversation
|
@JeffM2501 I see the issue but I want to review this change more carefully, waiting after 5.5 release for further discussion. |
Absolutely understandable |
| //---------------------------------------------------------------------------------- | ||
| typedef struct { int x; int y; } Point; | ||
| typedef struct { unsigned int width; unsigned int height; } Size; | ||
| typedef struct { int keycode; int scancode; } KeyCodes; |
There was a problem hiding this comment.
I'd call this struct KeyInfo to avoid confusion with keycode
| RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed | ||
| 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 GetKeyPressedPro(int* scanCode); // Get key pressed (keycode), and optional scancode, call it multiple times for keys queued, returns 0 when the queue is empty |
There was a problem hiding this comment.
As per raylib design, I try to minimize return-pointers when possible. I prefer a int GetKeyPressedRaw(void) function to note the raw nature (scancode) of returned key.
There was a problem hiding this comment.
The problem with making a function that just returns the scan code is that this pulls from the events. Calling that function will eat the event and prevent you from beeing able to get the Keyboard Key too.
There may be cases where the user wants both (such as for a "press a key" control config dialog), they need the KeyboardKey to use later for polling, but the scancode to be able to show the mapped key name.
The other option is to return the KeyInfo structure by value.
|
|
||
| CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = key; | ||
| CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount].keycode = key; | ||
| CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount].scancode = -1; |
There was a problem hiding this comment.
It seems scancode can be read with NDK AKeyEvent_getScanCode().
| // Get the last key pressed | ||
| int GetKeyPressed(void) | ||
| { | ||
| return GetKeyPressedPro(NULL); |
There was a problem hiding this comment.
Considering GetKeyPressed() is very short, I think code lines can be "duplicated" for GetKeyPressedRaw().
| { | ||
| CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = key; | ||
| CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount].keycode = key; | ||
| CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount].scancode = event->keyCode; |
There was a problem hiding this comment.
I'm curious, why key scancode is actually event->keyCode? @ColleagueRiley
|
Per our discussion on discord. |
use the correct value for virtual key from sdl.
…nflicting definitions of scancode in GFLW and SDL.
orcmid
left a comment
There was a problem hiding this comment.
I think the pair struct is valuable. mappedcode seems awkward (and I wonder about the absence of camelCase).
For me, I think of it as scanCode versus keyTop. And of course, that would normally depend on a keyboard binding, with a QWERTY ANSI keyboard the default. So that's murky too, since shift-state is also reflected. On the other hand, it might be more helpful for people to understand at least the default situation. Not proposing anything, just musing about the awkwardness of this situation.
|
@raysan5 After looking into GLFW's code with Jeff, I found that GLFW only supports the use of scancodes, but not keycodes. The |
|
Yes, after good discussion and research, it has been shown that GLFW doesn't support a mapped value, so this entire PR is pointless while GLTF is the default backend. I am going to close it and open a discussion where we can talk about what we want raylib to expose and come up with use cases. |
@JeffM2501 I am tempted to suggest that "mapped code" should be "keyedChar" (depending on type, since might not be u8, although "keyedGlyph" might be more accurate but not so understandable) that provides coordination with what an user sees themselves keying and what the application recognizes as keyed if reflected in a message and especially in an action. Somehow, the default case should just work in alignment with the original impetus for raylib (namely BGI) and the idea of simplicity. The question then becomes how to address some of these more-expanded use cases and computer configurations while being as simple as possible (but no simpler) in the main and in line with raylib as a learning instrument for graphical applications. PS: Some of us might be old enough to recall that WASD as arrow keys was introduced with teletype keyboards and early video consoles. It was used in text editors and word processors before there were PCs and Wintel (but Unix). I am unclear about when it became a typical keyboard-mouse mapping for interactive games. PPS: I don't think all of this can or should be handled under the covers by raylib. However, it would be great to have a reliable way to graft on additional facilities that work smoothly as raylib adjuncts. So raylib should enable without getting in the way while providing default paths that work as always. |
|
I have created a discussion topic here |
Currently raylib does not expose the scancode data for keyboard input received from the platform. This makes it VERY hard to build keyboard bindings that work with different keyboard mappings and localizations. They KeyboardKey enum is just the physical keys and does not take the keyboard mapping into account. For most game input this is fine, as you want the physical key, but there are use cases where you need local mapping of non-text keys.
GetCharPressed handles the mapping, but only for printable characters.
Any user that wants the 'logical' key that is provided by the keyboard mapping as no way to get this data.
The data was passed to the keyboard input functions of most platforms, but the raylib key system has no place to store it.
In SDL this scancode is the 'virtual key'
This PR adds GetKeyPressedPro that takes an optional scancode to fill out, allowing people to see the localized key for each event.
Platforms that don't provide a scancode set the code to -1.
I don't know if this should go into 5.5 or if we should discuss the API for the future. This is just the smallest possible change to raylib to expose the data that it's currently ignoring. I am just posting this so it doesn't get lost.