Get keycode from a NON human-readable name

Hey everyone.
I’m aware of the function SDL_GetKeyFromName that I use like this:
SDL_Keycode kc = SDL_GetKeyFromName("\r");

Is there a way to get an SDL_Keycode by passing the internal keycode name? Something like this:
SDL_Keycode kc = SomeFunction(“SDLK_RETURN”);

The reason for that is that I have a config file for key-bindings in my app, and I’d prefer to parse “SDLK_xxx” strings instead of the human-readable strings.

Thanks in advance.

There is no function that does this - and I don’t think it’s possible in a generic way.
The problem is that not all keycodes have a corresponding SDLK_* constant - e.g. the Umlaut keys on German keyboards don’t (I think only ASCII-keys and non-character-keys have SDLK_* constants).
I think for character keys generally the unicode charcode is used?

Furthermore, I’d suggest to use scancodes instead of keycodes in config files (and as internal representation in the Engine) and use SDL_GetKeyName(SDL_GetKeyFromScancode(yourScancode)) to display the key name to the user (in the bindings menu or when showing hints what button to press in the game).
This way you can provide keyboard bindings that work on all keyboard layouts.
For example, WASD for movement doesn’t work on French “AZERTY” keyboards because those keys are at totally different places there. But if you use scancodes in your default config and then display the corresponding keys as shown above, it’d automatically map those keys to Z, Q, S, D.
Drawbacks:

  1. Unfortunately SDL_GetScancodeName() is not suitable for configs, as the names might be different on different systems (see https://wiki.libsdl.org/SDL_GetScancodeName)… so you’d have to either map them to/from stable strings yourself or save their numerical value instead… yes, this kinda sucks, there should be functions that maps them to/from "SDL_SCANCODE_*" (and in contrast to keycodes this is possible for scancodes).
  2. Sometimes the keycode is more meaningful than the keyboard position, e.g. “Press [M] to open the map” (OTOH if your game is translated, the word for “map” in a different language probably doesn’t start with “m”…)
1 Like

Thank you very much for the detailed response Daniel!
The reason I chose keycodes over scancodes is that I’m making a text-editor.
If I understand right(quoting a stackoverflow answer):

On an AZERTY keyboard, pressing A will emit a "Q" scancode and an "a" keycode.

Hopefully that means that an AZERTY user will look at the “A” key on his keyboard, press it, and see the “a” character on screen. Or when he uses a key-binding with that key, the binded command executes. That’s why I’m handling keycodes in my app and would want the same for my config file.

Anyway, given the fact that there’s no function for what I wanted (and I thank you very much for confirming that) it seems I’ll have to find another way.

For typed characters that end up on the screen you should use textinput events (otherwise things like Shift+1 won’t work properly, as the resulting character depends on the keyboard layout).

For using keycodes in the config, you could map the known keycodes manually (copy the list from the SDL enum in the header and modify it, shouldn’t be that much work). Everything else should be some kind of unicode character, so you could just convert the keycode from UTF32 to UTF8 (or whatever your config is in) and save that.
I’d probably use an X macro for the mapping like

#define MY_SDL_KEYCODES \
    MY_KEYCODE_ENTRY(SDLK_RETURN) \
    MY_KEYCODE_ENTRY(SDLK_ESCAPE) \
    // .. etc

so you can generate the code for mapping from that, like

const char* mySDLkeycodeToString(SDL_Keycode k) {
#define MY_KEYCODE_ENTRY(X) case X: return #X;
    switch(k) {
        // this will be expanded to case SDLK_bla : return "SDLK_bla";
        // for each entry in MY_SDL_KEYCODES
        MY_SDL_KEYCODES
    }
#undef MY_KEYCODE_ENTRY
    return NULL; // or do the unicode conversion thing here
    // or maybe just return SDL_GetKeyName(k);
    // I guess it's stable for character keys?
}

(and similar for the string => keycode case)

1 Like

Once again, I can’t thank you enough!
I’m already using textinput for character entry, what I really wanted to emphasize is that keycodes seemed more appropriate for a text-editor compared to a game.

I wasn’t aware of the X macro technique, as I’m at a skill level between a noob and an advanced noob (XD), so I’ll try to grasp the rest of your answer which seems genius!

1 Like

Yeah, keycodes might make more sense, because we’re used to Ctrl-C, Ctrl-Z etc, independent of keyboard layout.

https://en.wikipedia.org/wiki/X_Macro has some more info on X Macros (incl. links to articles about them; I think I first read about it in that article from Walter Bright)

1 Like