(click to interact)
(mouseover/click to play GIF)
Interactive demo (if JavaScript is enabled)
This is a small post about how to convert key codes to key names and/or convert key names to key codes. Comes with sample code for GameMaker and a generic version.
Mostly published because it covers majority of common and semi-common buttons.
The idea
You fill up a couple of global lookup tables with human-readable names and key codes that you got via experimentation (keyboard_lastkey in GameMaker, keyboard events or even from just polling all available buttons in other languages) and use those later.
If your language of choice has fast and fancy switch statements, you may use those instead, but it is rare that such functionality is used at frequency where performance matters too much.
For GameMaker
First, the initialization. This would have to be done once on game start:
var l_c2s = ds_map_create(); global.keyboard_key_to_name = l_c2s; var l_s2c = ds_map_create(); global.keyboard_name_to_key = l_s2c; var l_k, l_c, l_s, l_slq; l_c2s[?27] = "Escape"; l_s2c[?"escape"] = 27; l_s2c[?"esc"] = 27; l_c2s[?32] = "Space"; l_s2c[?"space"] = 32; l_s2c[?"spacebar"] = 32; l_c2s[?13] = "Enter"; l_s2c[?"enter"] = 13; l_s2c[?"return"] = 13; l_c2s[?37] = "Left"; l_s2c[?"left"] = 37; l_c2s[?39] = "Right"; l_s2c[?"right"] = 39; l_c2s[?38] = "Up"; l_s2c[?"up"] = 38; l_c2s[?40] = "Down"; l_s2c[?"down"] = 40; l_c2s[?8] = "Backspace"; l_s2c[?"backspace"] = 8; l_s2c[?"bksp"] = 8; l_c2s[?9] = "Tab"; l_s2c[?"tab"] = 9; l_c2s[?16] = "Shift"; l_s2c[?"shift"] = 16; l_c2s[?17] = "Control"; l_s2c[?"control"] = 17; l_s2c[?"ctrl"] = 17; l_c2s[?18] = "Alt"; l_s2c[?"alt"] = 18; l_c2s[?19] = "Pause"; l_s2c[?"pause"] = 19; l_s2c[?"break"] = 19; l_c2s[?20] = "Capslock"; l_s2c[?"capslock"] = 20; l_s2c[?"caps"] = 20; l_c2s[?160] = "LeftShift"; l_s2c[?"leftshift"] = 160; l_s2c[?"lshift"] = 160; l_c2s[?161] = "RightShift"; l_s2c[?"rightshift"] = 161; l_s2c[?"rshift"] = 161; l_c2s[?162] = "LeftControl"; l_s2c[?"leftcontrol"] = 162; l_s2c[?"lcontrol"] = 162; l_s2c[?"lctrl"] = 162; l_c2s[?163] = "RightControl"; l_s2c[?"rightcontrol"] = 163; l_s2c[?"rcontrol"] = 163; l_s2c[?"rctrl"] = 163; l_c2s[?164] = "LeftAlt"; l_s2c[?"leftalt"] = 164; l_s2c[?"lalt"] = 164; l_c2s[?165] = "RightAlt"; l_s2c[?"rightalt"] = 165; l_s2c[?"ralt"] = 165; l_c2s[?91] = "Windows"; l_s2c[?"windows"] = 91; l_s2c[?"system"] = 91; l_s2c[?"win"] = 91; l_s2c[?"sys"] = 91; l_c2s[?92] = "RightWindows"; l_s2c[?"rightwindows"] = 92; l_s2c[?"rightsystem"] = 92; l_s2c[?"rwin"] = 92; l_s2c[?"rsys"] = 92; l_c2s[?33] = "PageUp"; l_s2c[?"pageup"] = 33; l_s2c[?"pgup"] = 33; l_c2s[?34] = "PageDown"; l_s2c[?"pagedown"] = 34; l_s2c[?"pgdown"] = 34; l_c2s[?35] = "End"; l_s2c[?"end"] = 35; l_c2s[?36] = "Home"; l_s2c[?"home"] = 36; l_c2s[?44] = "PrintScreen"; l_s2c[?"printscreen"] = 44; l_s2c[?"prtscr"] = 44; l_s2c[?"sysrq"] = 44; l_c2s[?45] = "Insert"; l_s2c[?"insert"] = 45; l_s2c[?"ins"] = 45; l_c2s[?46] = "Delete"; l_s2c[?"delete"] = 46; l_s2c[?"del"] = 46; l_c2s[?145] = "ScrollLock"; l_s2c[?"scrolllock"] = 145; l_s2c[?"scrlck"] = 145; l_c2s[?186] = "Semicolon"; l_s2c[?"semicolon"] = 186; l_s2c[?"colon"] = 186; l_s2c[?":"] = 186; l_s2c[?";"] = 186; l_c2s[?187] = "Equals"; l_s2c[?"equals"] = 187; l_s2c[?"="] = 187; l_c2s[?188] = "Comma"; l_s2c[?"comma"] = 188; l_s2c[?"less"] = 188; l_s2c[?","] = 188; l_s2c[?"<"] = 188; l_c2s[?189] = "Underscore"; l_s2c[?"underscore"] = 189; l_s2c[?"_"] = 189; l_c2s[?190] = "Period"; l_s2c[?"period"] = 190; l_s2c[?"dot"] = 190; l_s2c[?"more"] = 190; l_s2c[?"."] = 190; l_s2c[?">"] = 190; l_c2s[?191] = "Slash"; l_s2c[?"slash"] = 191; l_s2c[?"?"] = 191; l_s2c[?"/"] = 191; l_c2s[?192] = "Tilde"; l_s2c[?"tilde"] = 192; l_s2c[?"~"] = 192; l_s2c[?"`"] = 192; l_c2s[?219] = "OpenBracket"; l_s2c[?"openbracket"] = 219; l_s2c[?"["] = 219; l_s2c[?"{"] = 219; l_c2s[?220] = "BackSlash"; l_s2c[?"backslash"] = 220; l_s2c[?chr(92)/* "\" */] = 220; l_s2c[?"|"] = 220; l_c2s[?221] = "CloseBracket"; l_s2c[?"closebracket"] = 221; l_s2c[?"]"] = 221; l_s2c[?"}"] = 221; l_c2s[?222] = "Quote"; l_s2c[?"quote"] = 222; l_s2c[?"apostrophe"] = 222; l_s2c[?"'"] = 222; l_s2c[?chr(34)/* '"' */] = 222; for (l_k = 65; l_k <= 90; l_k += 1) { l_c = chr(l_k); l_c2s[?l_k] = l_c; l_slq = string_lower(l_c); l_s2c[?l_slq] = l_k; } l_c2s[?48] = "D0"; l_s2c[?"d0"] = 48; l_s2c[?"dig0"] = 48; l_s2c[?"digit0"] = 48; l_s2c[?"0"] = 48; l_c2s[?49] = "D1"; l_s2c[?"d1"] = 49; l_s2c[?"dig1"] = 49; l_s2c[?"digit1"] = 49; l_s2c[?"1"] = 49; l_c2s[?50] = "D2"; l_s2c[?"d2"] = 50; l_s2c[?"dig2"] = 50; l_s2c[?"digit2"] = 50; l_s2c[?"2"] = 50; l_c2s[?51] = "D3"; l_s2c[?"d3"] = 51; l_s2c[?"dig3"] = 51; l_s2c[?"digit3"] = 51; l_s2c[?"3"] = 51; l_c2s[?52] = "D4"; l_s2c[?"d4"] = 52; l_s2c[?"dig4"] = 52; l_s2c[?"digit4"] = 52; l_s2c[?"4"] = 52; l_c2s[?53] = "D5"; l_s2c[?"d5"] = 53; l_s2c[?"dig5"] = 53; l_s2c[?"digit5"] = 53; l_s2c[?"5"] = 53; l_c2s[?54] = "D6"; l_s2c[?"d6"] = 54; l_s2c[?"dig6"] = 54; l_s2c[?"digit6"] = 54; l_s2c[?"6"] = 54; l_c2s[?55] = "D7"; l_s2c[?"d7"] = 55; l_s2c[?"dig7"] = 55; l_s2c[?"digit7"] = 55; l_s2c[?"7"] = 55; l_c2s[?56] = "D8"; l_s2c[?"d8"] = 56; l_s2c[?"dig8"] = 56; l_s2c[?"digit8"] = 56; l_s2c[?"8"] = 56; l_c2s[?57] = "D9"; l_s2c[?"d9"] = 57; l_s2c[?"dig9"] = 57; l_s2c[?"digit9"] = 57; l_s2c[?"9"] = 57; for (l_k = 112; l_k < 136; l_k += 1) { l_c = "F" + string(l_k - 111); l_c2s[?l_k] = l_c; l_slq = string_lower(l_c); l_s2c[?l_slq] = l_k; } l_c2s[?144] = "Numlock"; l_s2c[?"numlock"] = 144; l_c2s[?111] = "Divide"; l_s2c[?"divide"] = 111; l_s2c[?"div"] = 111; l_s2c[?"numdiv"] = 111; l_s2c[?"/"] = 111; l_c2s[?106] = "Multiply"; l_s2c[?"multiply"] = 106; l_s2c[?"mul"] = 106; l_s2c[?"nummul"] = 106; l_s2c[?"*"] = 106; l_c2s[?107] = "Add"; l_s2c[?"add"] = 107; l_s2c[?"plus"] = 107; l_s2c[?"numadd"] = 107; l_s2c[?"+"] = 107; l_c2s[?109] = "Subtract"; l_s2c[?"subtract"] = 109; l_s2c[?"minus"] = 109; l_s2c[?"numsub"] = 109; l_s2c[?"-"] = 109; l_c2s[?110] = "NumpadDelete"; l_s2c[?"numpaddelete"] = 110; l_s2c[?"numdel"] = 110; l_s2c[?"numperiod"] = 110; for (l_k = 96; l_k < 106; l_k += 1) { l_c = string(l_k - 96); l_s = "Numpad" + l_c; l_c2s[?l_k] = l_c; l_slq = string_lower(l_c); l_s2c[?l_slq] = l_k; l_s = "Num" + l_c; l_slq = string_lower(l_s); l_s2c[?l_slq] = l_k; } l_s2c[?""] = 0; l_s2c[?"none"] = 0; l_c2s[?0] = "None"; for (l_k = 1; l_k < 256; l_k += 1) { l_s = "Key" + string(l_k); if (!ds_map_exists(l_c2s, l_k)) l_c2s[?l_k] = l_s; l_slq = string_lower(l_s); l_s2c[?l_slq] = l_k; }
Then, you could have a script like keyboard_key_name that does
/// keyboard_key_name(keycode:int) var name = global.keyboard_key_to_name[?argument0]; if (name == undefined) return ""; return name;
and keyboard_key_code that does
/// keyboard_key_code(keyname:string) var k = global.keyboard_name_to_key[?string_lower(argument0)]; if (k == undefined) return -1; return k;
and use them as you please.
For other languages
To make this as generalized as possible, the code here is just a flattened version of original - in other words, a pile of calls to a function that you'd have to do the actual setup.
This is for converting key codes to key names:
setKeyName(27, "Escape"); setKeyName(32, "Space"); setKeyName(13, "Enter"); setKeyName(37, "Left"); setKeyName(39, "Right"); setKeyName(38, "Up"); setKeyName(40, "Down"); setKeyName(8, "Backspace"); setKeyName(9, "Tab"); setKeyName(16, "Shift"); setKeyName(17, "Control"); setKeyName(18, "Alt"); setKeyName(19, "Pause"); setKeyName(20, "Capslock"); setKeyName(160, "LeftShift"); setKeyName(161, "RightShift"); setKeyName(162, "LeftControl"); setKeyName(163, "RightControl"); setKeyName(164, "LeftAlt"); setKeyName(165, "RightAlt"); setKeyName(91, "Windows"); setKeyName(92, "RightWindows"); setKeyName(33, "PageUp"); setKeyName(34, "PageDown"); setKeyName(35, "End"); setKeyName(36, "Home"); setKeyName(44, "PrintScreen"); setKeyName(45, "Insert"); setKeyName(46, "Delete"); setKeyName(145, "ScrollLock"); setKeyName(186, "Semicolon"); setKeyName(187, "Equals"); setKeyName(188, "Comma"); setKeyName(189, "Underscore"); setKeyName(190, "Period"); setKeyName(191, "Slash"); setKeyName(192, "Tilde"); setKeyName(219, "OpenBracket"); setKeyName(220, "BackSlash"); setKeyName(221, "CloseBracket"); setKeyName(222, "Quote"); setKeyName(65, "A"); setKeyName(66, "B"); setKeyName(67, "C"); setKeyName(68, "D"); setKeyName(69, "E"); setKeyName(70, "F"); setKeyName(71, "G"); setKeyName(72, "H"); setKeyName(73, "I"); setKeyName(74, "J"); setKeyName(75, "K"); setKeyName(76, "L"); setKeyName(77, "M"); setKeyName(78, "N"); setKeyName(79, "O"); setKeyName(80, "P"); setKeyName(81, "Q"); setKeyName(82, "R"); setKeyName(83, "S"); setKeyName(84, "T"); setKeyName(85, "U"); setKeyName(86, "V"); setKeyName(87, "W"); setKeyName(88, "X"); setKeyName(89, "Y"); setKeyName(90, "Z"); setKeyName(48, "D0"); setKeyName(49, "D1"); setKeyName(50, "D2"); setKeyName(51, "D3"); setKeyName(52, "D4"); setKeyName(53, "D5"); setKeyName(54, "D6"); setKeyName(55, "D7"); setKeyName(56, "D8"); setKeyName(57, "D9"); setKeyName(112, "F1"); setKeyName(113, "F2"); setKeyName(114, "F3"); setKeyName(115, "F4"); setKeyName(116, "F5"); setKeyName(117, "F6"); setKeyName(118, "F7"); setKeyName(119, "F8"); setKeyName(120, "F9"); setKeyName(121, "F10"); setKeyName(122, "F11"); setKeyName(123, "F12"); setKeyName(124, "F13"); setKeyName(125, "F14"); setKeyName(126, "F15"); setKeyName(127, "F16"); setKeyName(128, "F17"); setKeyName(129, "F18"); setKeyName(130, "F19"); setKeyName(131, "F20"); setKeyName(132, "F21"); setKeyName(133, "F22"); setKeyName(134, "F23"); setKeyName(135, "F24"); setKeyName(144, "Numlock"); setKeyName(111, "Divide"); setKeyName(106, "Multiply"); setKeyName(107, "Add"); setKeyName(109, "Subtract"); setKeyName(110, "NumpadDelete"); setKeyName(96, "0"); setKeyName(97, "1"); setKeyName(98, "2"); setKeyName(99, "3"); setKeyName(100, "4"); setKeyName(101, "5"); setKeyName(102, "6"); setKeyName(103, "7"); setKeyName(104, "8"); setKeyName(105, "9");
This is for converting lower-case key names (with variants where it made sense to) to key codes:
setKeyCode("escape", 27); setKeyCode("esc", 27); setKeyCode("space", 32); setKeyCode("spacebar", 32); setKeyCode("enter", 13); setKeyCode("return", 13); setKeyCode("left", 37); setKeyCode("right", 39); setKeyCode("up", 38); setKeyCode("down", 40); setKeyCode("backspace", 8); setKeyCode("bksp", 8); setKeyCode("tab", 9); setKeyCode("shift", 16); setKeyCode("control", 17); setKeyCode("ctrl", 17); setKeyCode("alt", 18); setKeyCode("pause", 19); setKeyCode("break", 19); setKeyCode("capslock", 20); setKeyCode("caps", 20); setKeyCode("leftshift", 160); setKeyCode("lshift", 160); setKeyCode("rightshift", 161); setKeyCode("rshift", 161); setKeyCode("leftcontrol", 162); setKeyCode("lcontrol", 162); setKeyCode("lctrl", 162); setKeyCode("rightcontrol", 163); setKeyCode("rcontrol", 163); setKeyCode("rctrl", 163); setKeyCode("leftalt", 164); setKeyCode("lalt", 164); setKeyCode("rightalt", 165); setKeyCode("ralt", 165); setKeyCode("windows", 91); setKeyCode("system", 91); setKeyCode("win", 91); setKeyCode("sys", 91); setKeyCode("rightwindows", 92); setKeyCode("rightsystem", 92); setKeyCode("rwin", 92); setKeyCode("rsys", 92); setKeyCode("pageup", 33); setKeyCode("pgup", 33); setKeyCode("pagedown", 34); setKeyCode("pgdown", 34); setKeyCode("end", 35); setKeyCode("home", 36); setKeyCode("printscreen", 44); setKeyCode("prtscr", 44); setKeyCode("sysrq", 44); setKeyCode("insert", 45); setKeyCode("ins", 45); setKeyCode("delete", 46); setKeyCode("del", 46); setKeyCode("scrolllock", 145); setKeyCode("scrlck", 145); setKeyCode("semicolon", 186); setKeyCode("colon", 186); setKeyCode(":", 186); setKeyCode(";", 186); setKeyCode("equals", 187); setKeyCode("=", 187); setKeyCode("comma", 188); setKeyCode("less", 188); setKeyCode(",", 188); setKeyCode("<", 188); setKeyCode("underscore", 189); setKeyCode("_", 189); setKeyCode("period", 190); setKeyCode("dot", 190); setKeyCode("more", 190); setKeyCode(".", 190); setKeyCode(">", 190); setKeyCode("slash", 191); setKeyCode("?", 191); setKeyCode("/", 191); setKeyCode("tilde", 192); setKeyCode("~", 192); setKeyCode("`", 192); setKeyCode("openbracket", 219); setKeyCode("[", 219); setKeyCode("{", 219); setKeyCode("backslash", 220); setKeyCode("\\", 220); // (backslash character) setKeyCode("|", 220); setKeyCode("closebracket", 221); setKeyCode("]", 221); setKeyCode("}", 221); setKeyCode("quote", 222); setKeyCode("apostrophe", 222); setKeyCode("'", 222); setKeyCode("\"", 222); // (double quote character) setKeyCode("a", 65); setKeyCode("b", 66); setKeyCode("c", 67); setKeyCode("d", 68); setKeyCode("e", 69); setKeyCode("f", 70); setKeyCode("g", 71); setKeyCode("h", 72); setKeyCode("i", 73); setKeyCode("j", 74); setKeyCode("k", 75); setKeyCode("l", 76); setKeyCode("m", 77); setKeyCode("n", 78); setKeyCode("o", 79); setKeyCode("p", 80); setKeyCode("q", 81); setKeyCode("r", 82); setKeyCode("s", 83); setKeyCode("t", 84); setKeyCode("u", 85); setKeyCode("v", 86); setKeyCode("w", 87); setKeyCode("x", 88); setKeyCode("y", 89); setKeyCode("z", 90); setKeyCode("d0", 48); setKeyCode("dig0", 48); setKeyCode("digit0", 48); setKeyCode("0", 48); setKeyCode("d1", 49); setKeyCode("dig1", 49); setKeyCode("digit1", 49); setKeyCode("1", 49); setKeyCode("d2", 50); setKeyCode("dig2", 50); setKeyCode("digit2", 50); setKeyCode("2", 50); setKeyCode("d3", 51); setKeyCode("dig3", 51); setKeyCode("digit3", 51); setKeyCode("3", 51); setKeyCode("d4", 52); setKeyCode("dig4", 52); setKeyCode("digit4", 52); setKeyCode("4", 52); setKeyCode("d5", 53); setKeyCode("dig5", 53); setKeyCode("digit5", 53); setKeyCode("5", 53); setKeyCode("d6", 54); setKeyCode("dig6", 54); setKeyCode("digit6", 54); setKeyCode("6", 54); setKeyCode("d7", 55); setKeyCode("dig7", 55); setKeyCode("digit7", 55); setKeyCode("7", 55); setKeyCode("d8", 56); setKeyCode("dig8", 56); setKeyCode("digit8", 56); setKeyCode("8", 56); setKeyCode("d9", 57); setKeyCode("dig9", 57); setKeyCode("digit9", 57); setKeyCode("9", 57); setKeyCode("f1", 112); setKeyCode("f2", 113); setKeyCode("f3", 114); setKeyCode("f4", 115); setKeyCode("f5", 116); setKeyCode("f6", 117); setKeyCode("f7", 118); setKeyCode("f8", 119); setKeyCode("f9", 120); setKeyCode("f10", 121); setKeyCode("f11", 122); setKeyCode("f12", 123); setKeyCode("f13", 124); setKeyCode("f14", 125); setKeyCode("f15", 126); setKeyCode("f16", 127); setKeyCode("f17", 128); setKeyCode("f18", 129); setKeyCode("f19", 130); setKeyCode("f20", 131); setKeyCode("f21", 132); setKeyCode("f22", 133); setKeyCode("f23", 134); setKeyCode("f24", 135); setKeyCode("numlock", 144); setKeyCode("divide", 111); setKeyCode("div", 111); setKeyCode("numdiv", 111); setKeyCode("/", 111); setKeyCode("multiply", 106); setKeyCode("mul", 106); setKeyCode("nummul", 106); setKeyCode("*", 106); setKeyCode("add", 107); setKeyCode("plus", 107); setKeyCode("numadd", 107); setKeyCode("+", 107); setKeyCode("subtract", 109); setKeyCode("minus", 109); setKeyCode("numsub", 109); setKeyCode("-", 109); setKeyCode("numpaddelete", 110); setKeyCode("numdel", 110); setKeyCode("numperiod", 110); setKeyCode("0", 96); setKeyCode("num0", 96); setKeyCode("1", 97); setKeyCode("num1", 97); setKeyCode("2", 98); setKeyCode("num2", 98); setKeyCode("3", 99); setKeyCode("num3", 99); setKeyCode("4", 100); setKeyCode("num4", 100); setKeyCode("5", 101); setKeyCode("num5", 101); setKeyCode("6", 102); setKeyCode("num6", 102); setKeyCode("7", 103); setKeyCode("num7", 103); setKeyCode("8", 104); setKeyCode("num8", 104); setKeyCode("9", 105); setKeyCode("num9", 105);
Key codes are largely as per virtual key format, which is fairly standard, but does not match up with key codes on Android, for example.
Bonus: a tileset with images for virtual key codes specifically.
Was this code originally Haxe code?
It was compiled from Haxe to GML, yeah
I knew it! Good job friend
There’s an error in line 140 init script btw
>l_s2c[?’ ” ‘] = 222
instead of
l_s2c[?” ‘ “] = 222;
In GMS2 it’d have to be either that,
l_s2c[?@'"']
orl_s2c[?"\""]
because single-quote strings have been eliminated.Doesn’t work.
Script: Keyboard_key_name at line 140 : invalid token
That was because WordPress replaces quotation marks with “fancy” ones in comments by default, though that should have been possible to figure out yourself.
I have now updated the code in the post to not need GMS1/GMS2 differences.
Nice! Loved the bonus tile.