Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDL2: key.keycode.sym returns a scancode instead of a keycode #21377

Closed
giogadi opened this issue Feb 20, 2024 · 13 comments
Closed

SDL2: key.keycode.sym returns a scancode instead of a keycode #21377

giogadi opened this issue Feb 20, 2024 · 13 comments

Comments

@giogadi
Copy link

giogadi commented Feb 20, 2024

(I also posted this issue on the SDL repo here)

When I inspect the keycode associated with a keydown event using event.key.keysym.sym, the value returned is a SDL_Scancode instead of a SDL_Keycode. I would expect event.key.keysym.sym to return a SDL_Keycode according to the SDL documentation. Example:

SDL_Event e;
while (SDL_PollEvent(&e) != 0) {
    if (e.type == SDL_KEYDOWN) {
        if (e.key.keysym.sym == SDLK_a) {
            printf("When I press the A key on my keyboard, this branch does NOT execute\n");
        } else if (e.key.keysym.sym == SDL_SCANCODE_A) {
            printf("This branch DOES execute when I press the A key on my keyboard.\n");
        }
    }
}

I'm using Emscripten 3.1.54, which uses SDL 2.26.0. I'm compiling the code with the following command:

emcc main.c -o index.html -sUSE_SDL=2

I'm opening the generated page in Chrome Version 121.0.6167.160 on MacOS 11.7.10.

Version of emscripten/emsdk:

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.54 (a95c44ee924d02fa1498f846595485d27c31daa8)
clang version 19.0.0git (https://github.com/llvm/llvm-project e769fb8699e3fa8e40623764f7713bfc783b0330)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /Users/luis/code/emsdk/upstream/bin

Full link command and output with -v appended:
log.txt

@sbc100
Copy link
Collaborator

sbc100 commented Feb 20, 2024

This this change with the recent SDL2 version bump (#21337)? i.e. can you reproduce this on emscripten versions older than 3.1.54?

@Daft-Freak WDYT?

@Daft-Freak
Copy link
Collaborator

I'd guess this is something to do with libsdl-org/SDL@9221548 as we didn't set keycodes/.sym before that. Not sure where that's going wrong though.

Also, I think some of the tests are checking keycodes?

@giogadi
Copy link
Author

giogadi commented Feb 21, 2024

Just in case this helps: for all the keys I've checked, event.key.keysym.sym seems to return the "correct" corresponding scancode, but event.key.keysym.scancode always returns 1, no matter what key I press.

@giogadi
Copy link
Author

giogadi commented Feb 21, 2024

This this change with the recent SDL2 version bump (#21337)? i.e. can you reproduce this on emscripten versions older than 3.1.54?

@Daft-Freak WDYT?

BTW I tried with 3.1.53, which does not include the SDL2 version bump, and I ran into the same problem.

@Daft-Freak
Copy link
Collaborator

I haven't managed to reproduce this, always getting the "this branch does NOT execute" message.

Using this full test program:

#include <stdio.h>
#include <SDL.h>
#include <emscripten.h>

void loop() {
    SDL_Event e;
    while (SDL_PollEvent(&e) != 0) {
      if (e.type == SDL_KEYDOWN) {
            if (e.key.keysym.sym == SDLK_a) {
                printf("When I press the A key on my keyboard, this branch does NOT execute\n");
            } else if (e.key.keysym.sym == SDL_SCANCODE_A) {
                printf("This branch DOES execute when I press the A key on my keyboard.\n");
            }

            printf("sym %i scancode %i\n", e.key.keysym.sym, e.key.keysym.scancode);
        }
    }
}

int main(int argc, char **argv) {
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window *window = SDL_CreateWindow("sdl2_key", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, 0);

    emscripten_set_main_loop(loop, 0, 1);

    return 0;
}

(Tried a few browser/OS combinations, including Chrome + macOS)

@giogadi
Copy link
Author

giogadi commented Feb 21, 2024

Oh my goodness. It turns out that my problem was in my headers: I was including <SDL/SDL.h> when I should have been including <SDL.h>. I dunno how that happened, but that fixes everything.

Sigh. Sorry to take up everybody's time with this. I wonder if there's a way to protect against a terrible mistake like this.

@Daft-Freak
Copy link
Collaborator

Ah, I should've noticed that your event fields were all off by one. Another issue caused by emscripten's weird "not SDL1.2, but not SDL2 either" headers 🤔

@sbc100
Copy link
Collaborator

sbc100 commented Feb 21, 2024

<SDL/SDL.h> will always give you SDL1 I believe.

<SDL2/SDL.h> will always give you SDL2 headers I believe.

If you only include <SDL.h> then the version of the header you get will depend on whether you specify -sUSE_SDL=2 or -sUSE_SDL=1. Those two flags will add either include/SDL or include/SDL2 to the include path respectively.

@sbc100
Copy link
Collaborator

sbc100 commented Feb 21, 2024

I checked again and it looks like <SDL/SDL.h> is always wrong if you want SDL2. If I'm correct then this is simple working as intendend and not an emscripten bug. Would you agree @Daft-Freak ?

If so I think we can close this issue?

@Daft-Freak
Copy link
Collaborator

Would be nice if the SDL1 headers didn't declare a bunch of SDL2 functions so things like this would fail earlier... but I guess that's another issue.

@sbc100
Copy link
Collaborator

sbc100 commented Feb 21, 2024

Don't SDL1 and SDl2 share a lot of the same function names? Is there something about the SDL1 headers in emscripten that are different here compared to normal SDL1 headers?

@Daft-Freak
Copy link
Collaborator

Some parts are the same, but others like video are almost entirely different.

//SDL1
SDL_SetVideoMode
SDL_GetVideoSurface
SDL_Flip

//SDL2
SDL_CreateWindow
SDL_GetWindowSurface/SDL_CreateRenderer
SDL_UpdateWindowSurface/SDL_RenderPresent

The headers in emscripten are from SDL1.3 (early pre-release SDL2), which defines both, but most of the new API isn't implemented in library_sdl.js. (I can see a stub for SDL_DestroyWindow, but not SDL_CreateWindow?)

The main side-effect of this being that if you include the wrong header by accident, SDL2 code usually compiles but as the structs are outdated you get issues like this one.

@sbc100
Copy link
Collaborator

sbc100 commented Feb 21, 2024

Thanks for the explanation. I guess its too late (or not worth) it to revert or SDL1 headers to true SDL1. We could at least try to trim them to stuff that we support.. but thats also outside the scope of this bug.

I think we can close this one.

@sbc100 sbc100 closed this as completed Feb 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants