raysan5 / raylib

A simple and easy-to-use library to enjoy videogames programming
http://www.raylib.com
zlib License
21.41k stars 2.17k forks source link

[rcore_sdl] SDL does not handle keys case-insensitively #3838

Closed Sqvid closed 4 months ago

Sqvid commented 6 months ago

Please, before submitting a new issue verify and check:

Issue description

The SDL platform does not correctly convert SDL_Scancodes to raylib keys in a case-insensitive manner. Additionally non SDL_TEXTINPUT keys do not seem to be added to the input queue.

Environment

Platform: DESKTOP_SDL OS: Linux 6.6.17 OpenGL version string: 4.6 (Compatibility Profile) Mesa 23.3.5 GPU: AMD Ryzen 7 7840HS w/ Radeon 780M Graphics

Issue Screenshot

Screenshot_2024-02-26_18:06:16

Code Example

#include <iostream>

#include "raylib.h"

int main() {
    SetTraceLogLevel(LOG_WARNING);
    InitWindow(800, 600, "Bug");

    while (!WindowShouldClose()) {
        BeginDrawing();
        ClearBackground(RAYWHITE);

        while (int key = GetKeyPressed()) {
            std::cout << "You pressed: '" << char(key) << "'" << ", CODE: " << key << "\n";
        }

        EndDrawing();
    }

    CloseWindow();
    return 0;
}

With the following changes to rcore_desktop_sdl.c:

diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c
index f567119e..4c643d55 100644
--- a/src/platforms/rcore_desktop_sdl.c
+++ b/src/platforms/rcore_desktop_sdl.c
@@ -49,6 +49,7 @@
 **********************************************************************************************/

 #include "SDL.h"                // SDL base library (window/rendered, input, timing... functionality)
+#include <stdio.h>

 #if defined(GRAPHICS_API_OPENGL_ES2)
     // It seems it does not need to be included to work
@@ -1116,6 +1117,7 @@ void PollInputEvents(void)
             // Keyboard events
             case SDL_KEYDOWN:
             {
+               printf("KEYDOWN\n");
                 KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode);
                 if (key != KEY_NULL) CORE.Input.Keyboard.currentKeyState[key] = 1;

@@ -1130,12 +1132,14 @@ void PollInputEvents(void)

             case SDL_KEYUP:
             {
+               printf("KEYUP\n");
                 KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode);
                 if (key != KEY_NULL) CORE.Input.Keyboard.currentKeyState[key] = 0;
             } break;

             case SDL_TEXTINPUT:
             {
+               printf("TEXTINPUT\n");
                 // NOTE: event.text.text data comes an UTF-8 text sequence but we register codepoints (int)

                 int codepointSize = 0;
@@ -1602,6 +1606,7 @@ static KeyboardKey ConvertScancodeToKey(SDL_Scancode sdlScancode)
 {
     if (sdlScancode >= 0 && sdlScancode < SCANCODE_MAPPED_NUM)
     {
+       printf("scancode: %d\n", sdlScancode);
         return ScancodeToKey[sdlScancode];
     }
     return KEY_NULL; // No equivalent key in Raylib
Sqvid commented 6 months ago

Keys like KEY_ENTER do not trigger the TEXTINPUT case and therefore do not get added to the input queue. I am happy to submit a PR if one of the maintainers can suggest how to resolve this difference between GLFW and SDL.

I want to point out that the main problem with this is that if someone hits the 'S' key on their keyboard then a lowercase 's' is returned which does not trigger a KEY_S case statement. The comments in rcore.c suggest the intended behaviour is that KEY_S should capture 'S' or 's'. This means only SHIFT+s triggers the case statement.

raysan5 commented 6 months ago

@Sqvid At the moment I don't know how it can be addressed but both implementations should be consistent and it should also be compatible with previous raylib implementations.

raysan5 commented 4 months ago

I think a possible solution to this issue is using GetCharPressed().