1
\$\begingroup\$

Given a file mapping keys to controls, such as this:

up         w
down       s
left       a
right      d
jump   space
run    shift
crouch  ctrl

The values need to be converted into game commands, and constants. The commands aren't so much a problem as the keyboard keys are; a keyboard can contain over 100 keys, so the last thing desired is this:

unsigned int pressedKey;
if (value == "a") {
    pressedKey = KEY_A;
} else if (value == "b") {
    pressedKey = KEY_B;
} else if (value == "c") {
    pressedKey = KEY_C;
} else if...

What comes to mind would be to build a map of key value pairs, something like this:

std::unordered_map<std::string, unsigned int> keyFinder;
keyFinder.emplace("a", KEY_A);
keyFinder.emplace("b", KEY_B);
keyFinder.emplace("c", KEY_C);
// and so on

This would allow for fast lookups, but on the downside it still has to be hardcoded, and it's not going to be a pretty segment of code.

I'd love to hear some good solutions for reading a file and using it to map controls! If it involves using some other file format, that's fine too, as long as it's human readable.

\$\endgroup\$
5
  • \$\begingroup\$ I think this question would fit better on Stack Overflow than Gamedev. Regardless, if you're trying to cast a char to an unsigned int, check out this thread. \$\endgroup\$
    – igrad
    Commented Mar 5, 2014 at 1:53
  • \$\begingroup\$ I disagree; this seems reasonably game development focused. I also don't believe that SO thread really has anything to do with what the asker is looking for. \$\endgroup\$
    – user1430
    Commented Mar 5, 2014 at 2:55
  • \$\begingroup\$ Why does "human readable" matter? GUI or bust, preferably in-game. Even of the format is easy, the values are not: is it Spave or space or " " or what? PrintScreen or PrntScrn or "Print Screen"? Esc or Escape? How do you write out analog controls? Key conbinations? Gestures? Use a GUI, don't care if the format is human readable. \$\endgroup\$ Commented Mar 5, 2014 at 3:21
  • \$\begingroup\$ What is your engine or framework? It probably provides this functionality already. Otherwise, what's wrong with hardcoding the mapping? It's not like keyboards change that often. \$\endgroup\$ Commented Mar 5, 2014 at 5:14
  • \$\begingroup\$ @SeanMiddleditch The "final" product will definitely have the aforementioned GUI. Until then, though, I plan on having a default set of keybindings. If someone testing the game wants to modify those defaults, I'll point them towards the file (and a README). \$\endgroup\$
    – Fault
    Commented Mar 5, 2014 at 10:56

1 Answer 1

1
\$\begingroup\$

Keep it simple. I think you should use a map (like your unordered_map example). And you should just hard code the entire map like you suggested:

std::unordered_map<std::string, unsigned int> keyFinder;
keyFinder.emplace("a", KEY_A);
keyFinder.emplace("b", KEY_B);
keyFinder.emplace("c", KEY_C);
keyFinder.emplace("ctrl", KEY_CONTROL);
keyFinder.emplace("shift", KEY_SHIFT);
// ...

It's much easier and cleaner than correctly identifying the textual equivalents of all possible keys on all possible keyboards in a standard way. Keyboards are very complicated.

You can programmatically produce the mapping from key code to key text. On Windows, for example, iterate over every virtual key code, call MapVirtualKey to translate to scan codes, then call GetKeyNameText. There are similar processes for other operating systems. However, the key text you get back is set by the keyboard driver and translated based on the locale settings in almost all cases. This makes the data unreliable for use in configuration files.

A technique like the above can be useful for displaying the actual keys that a user should press (for example as part of an on-screen prompt), but not for producing a reliable textual mapping. Consequently, I think you are better off just hard-coding your desired mapping. Once you have this mapping to key names, put your key-name-to-action mappings in a JSON/XML/YAML/whatever-text-based-format-your-prefer file.

(Note that on some OSs, like Windows, the virtual key codes for A - Z map to the ASCII values for uppercase A - Z, so you can save yourself some typing there; you can find similarly exploitable patterns with numbers and F-keys, usually).


All of that said, I do agree with Sean's comment that you can avoid the need for this mapping entirely by providing good GUI support for adjusting keyboard bindings; then you can store out the locale-agnostic key values (virtual key codes on Windows) into your configuration file.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .