Skip to content

Commit 2b943bc

Browse files
authored
Key mapping fixes (#58)
* fix: Keys were mapped incorrectly in GLFW ImGui shared a workaround function that is copied here to remap from scancodes back to key values, as most users will use them * fix: Remove vestigial code * fix: Missed numpad 0 * fix: Remove extra print
1 parent 760bb41 commit 2b943bc

File tree

3 files changed

+30
-241
lines changed

3 files changed

+30
-241
lines changed

engine/system/win/sys_local.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ class sys_main_c: public sys_IMain {
4747

4848
bool Run(int argc, char** argv);
4949

50-
int KeyToVirtual(byte key);
51-
byte VirtualToKey(int virt);
52-
byte GlfwKeyToKey(int key);
50+
byte GlfwKeyToKey(int key, int scancode);
5351
char GlfwKeyExtraChar(int key);
5452

5553
#ifdef _WIN32

engine/system/win/sys_main.cpp

Lines changed: 28 additions & 237 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ static void SE_ErrorTrans(unsigned int code, EXCEPTION_POINTERS* exPtr)
4646
throw exPtr;
4747
}
4848
#endif
49+
#define GLFW_HAS_GET_KEY_NAME 1
4950

5051
// ===========
5152
// Timer class
@@ -231,248 +232,32 @@ bool find_c::FindNext()
231232
// Key Mapping
232233
// ===========
233234

234-
byte KeyRemapGLFW(int key) {
235-
if (key >= GLFW_KEY_0 && key <= GLFW_KEY_9) {
236-
return '0' + (key - GLFW_KEY_0);
237-
}
238-
if (key >= GLFW_KEY_A && key <= GLFW_KEY_Z) {
239-
return 'a' + (key - GLFW_KEY_A);
240-
}
241-
if (key >= GLFW_KEY_F1 && key <= GLFW_KEY_F15) {
242-
return KEY_F1 + (key - GLFW_KEY_F1);
243-
}
244-
switch (key) {
245-
case GLFW_KEY_BACKSPACE: return KEY_BACK;
246-
case GLFW_KEY_TAB: return KEY_TAB;
247-
case GLFW_KEY_ENTER: return KEY_RETURN;
248-
case GLFW_KEY_LEFT_SHIFT:
249-
case GLFW_KEY_RIGHT_SHIFT: return KEY_SHIFT;
250-
case GLFW_KEY_LEFT_CONTROL:
251-
case GLFW_KEY_RIGHT_CONTROL: return KEY_CTRL;
252-
case GLFW_KEY_LEFT_ALT:
253-
case GLFW_KEY_RIGHT_ALT: return KEY_ALT;
254-
case GLFW_KEY_PAUSE: return KEY_PAUSE;
255-
case GLFW_KEY_ESCAPE: return KEY_ESCAPE;
256-
case GLFW_KEY_SPACE: return ' ';
257-
case GLFW_KEY_PAGE_UP: return KEY_PGUP;
258-
case GLFW_KEY_PAGE_DOWN: return KEY_PGDN;
259-
case GLFW_KEY_END: return KEY_END;
260-
case GLFW_KEY_HOME: return KEY_HOME;
261-
case GLFW_KEY_LEFT: return KEY_LEFT;
262-
case GLFW_KEY_UP: return KEY_UP;
263-
case GLFW_KEY_RIGHT: return KEY_RIGHT;
264-
case GLFW_KEY_DOWN: return KEY_DOWN;
265-
case GLFW_KEY_PRINT_SCREEN: return KEY_PRINTSCRN;
266-
case GLFW_KEY_INSERT: return KEY_INSERT;
267-
case GLFW_KEY_DELETE: return KEY_DELETE;
268-
case GLFW_KEY_NUM_LOCK: return KEY_NUMLOCK;
269-
case GLFW_KEY_SCROLL_LOCK: return KEY_SCROLL;
270-
case GLFW_KEY_SEMICOLON: return ';';
271-
case GLFW_KEY_COMMA: return ',';
272-
case GLFW_KEY_MINUS: return '-';
273-
case GLFW_KEY_PERIOD: return '.';
274-
case GLFW_KEY_SLASH: return '/';
275-
case GLFW_KEY_GRAVE_ACCENT: return '`';
276-
case GLFW_KEY_LEFT_BRACKET: return '[';
277-
case GLFW_KEY_BACKSLASH: return '\\';
278-
case GLFW_KEY_RIGHT_BRACKET: return ']';
279-
case GLFW_KEY_APOSTROPHE: return '\'';
280-
}
281-
return 0;
282-
}
283-
284-
static const byte sys_keyRemap[] = {
285-
0, // 00 Null
286-
KEY_LMOUSE, // 01 VK_LBUTTON
287-
KEY_RMOUSE, // 02 VK_RBUTTON
288-
0, // 03 VK_CANCEL
289-
KEY_MMOUSE, // 04 VK_MBUTTON
290-
KEY_MOUSE4, // 05 VK_XBUTTON1
291-
KEY_MOUSE5, // 06 VK_XBUTTON2
292-
0, // 07 -
293-
KEY_BACK, // 08 VK_BACK
294-
KEY_TAB, // 09 VK_TAB
295-
0,0, // 0A 0B -
296-
0, // 0C VK_CLEAR
297-
KEY_RETURN, // 0D VK_RETUN
298-
0,0, // 0E 0F -
299-
KEY_SHIFT, // 10 VK_SHIFT
300-
KEY_CTRL, // 11 VK_CONTROL
301-
KEY_ALT, // 12 VK_MENU
302-
KEY_PAUSE, // 13 VK_PAUSE
303-
0, // 14 VK_CAPITAL
304-
0,0,0,0,0, // 15-19 IME
305-
0, // 1A -
306-
KEY_ESCAPE, // 1B VK_ESCAPE
307-
0,0,0,0, // 1C-1F IME
308-
' ', // 20 VK_SPACE
309-
KEY_PGUP, // 21 VK_PRIOR
310-
KEY_PGDN, // 22 VK_NEXT
311-
KEY_END, // 23 VK_END
312-
KEY_HOME, // 24 VK_HOME
313-
KEY_LEFT, // 25 VK_LEFT
314-
KEY_UP, // 26 VK_UP
315-
KEY_RIGHT, // 27 VK_RIGHT
316-
KEY_DOWN, // 28 VK_DOWN
317-
0, // 29 VK_SELECT
318-
0, // 2A VK_PRINT
319-
0, // 2B VK_EXECUTE
320-
KEY_PRINTSCRN, // 2C VK_SNAPSHOT
321-
KEY_INSERT, // 2D VK_INSERT
322-
KEY_DELETE, // 2E VK_DELETE
323-
0, // 2F VK_HELP
324-
'0', // 30 VK_0
325-
'1', // 31 VK_1
326-
'2', // 32 VK_2
327-
'3', // 33 VK_3
328-
'4', // 34 VK_4
329-
'5', // 35 VK_5
330-
'6', // 36 VK_6
331-
'7', // 37 VK_7
332-
'8', // 38 VK_8
333-
'9', // 39 VK_9
334-
0,0,0,0,0,0,0, // 3A-40 -
335-
'a', // 41 VK_A
336-
'b', // 42 VK_B
337-
'c', // 43 VK_C
338-
'd', // 44 VK_D
339-
'e', // 45 VK_E
340-
'f', // 46 VK_F
341-
'g', // 47 VK_G
342-
'h', // 48 VK_H
343-
'i', // 49 VK_I
344-
'j', // 4A VK_J
345-
'k', // 4B VK_K
346-
'l', // 4C VK_L
347-
'm', // 4D VK_M
348-
'n', // 4E VK_N
349-
'o', // 4F VK_O
350-
'p', // 50 VK_P
351-
'q', // 51 VK_Q
352-
'r', // 52 VK_R
353-
's', // 53 VK_S
354-
't', // 54 VK_T
355-
'u', // 55 VK_U
356-
'v', // 56 VK_V
357-
'w', // 57 VK_W
358-
'x', // 58 VK_X
359-
'y', // 59 VK_Y
360-
'z', // 5A VK_Z
361-
0, // 5B VK_LWIN
362-
0, // 5C VK_RWIN
363-
0, // 5D VK_APPS
364-
0, // 5E -
365-
0, // 5F VK_SLEEP
366-
'0', // 60 VK_NUMPAD0
367-
0, // 61 VK_NUMPAD1
368-
0, // 62 VK_NUMPAD2
369-
0, // 63 VK_NUMPAD3
370-
0, // 64 VK_NUMPAD4
371-
0, // 65 VK_NUMPAD5
372-
0, // 66 VK_NUMPAD6
373-
0, // 67 VK_NUMPAD7
374-
0, // 68 VK_NUMPAD8
375-
0, // 69 VK_NUMPAD9
376-
0, // 6A VK_MULTIPLY
377-
'+', // 6B VK_ADD
378-
0, // 6C VK_SEPARATOR
379-
'-', // 6D VK_SUBTRACT
380-
0, // 6E VK_DECIMAL
381-
0, // 6F VK_DIVIDE
382-
KEY_F1, // 70 VK_F1
383-
KEY_F2, // 71 VK_F2
384-
KEY_F3, // 72 VK_F3
385-
KEY_F4, // 73 VK_F4
386-
KEY_F5, // 74 VK_F5
387-
KEY_F6, // 75 VK_F6
388-
KEY_F7, // 76 VK_F7
389-
KEY_F8, // 77 VK_F8
390-
KEY_F9, // 78 VK_F9
391-
KEY_F10, // 79 VK_F10
392-
KEY_F11, // 7A VK_F11
393-
KEY_F12, // 7B VK_F12
394-
KEY_F13, // 7C VK_F13
395-
KEY_F14, // 7D VK_F14
396-
KEY_F15, // 7E VK_F15
397-
0, // 7F VK_F16
398-
0, // 80 VK_F17
399-
0, // 81 VK_F18
400-
0, // 82 VK_F19
401-
0, // 83 VK_F20
402-
0, // 84 VK_F21
403-
0, // 85 VK_F22
404-
0, // 86 VK_F23
405-
0, // 87 VK_F24
406-
0,0,0,0,0,0,0,0,// 88-8F -
407-
KEY_NUMLOCK, // 90 VK_NUMLOCK
408-
KEY_SCROLL, // 91 VK_SCROLL
409-
0,0,0,0,0, // 92-96 OEM
410-
0,0,0,0,0,0,0,0,0, // 97-9F -
411-
0, // A0 VK_LSHIFT
412-
0, // A1 VK_RSHIFT
413-
0, // A2 VK_LCONTROL
414-
0, // A3 VK_RCONTROL
415-
0, // A4 VK_LMENU
416-
0, // A5 VK_RMENU
417-
0, // A6 VK_BROWSER_BACK
418-
0, // A7 VK_BROWSER_FORWARD
419-
0, // A8 VK_BROWSER_REFRESH
420-
0, // A9 VK_BROWSER_STOP
421-
0, // AA VK_BROWSER_SEARCH
422-
0, // AB VK_BROWSER_FAVORITES
423-
0, // AC VK_BROWSER_HOME
424-
0, // AD VK_VOLUME_MUTE
425-
0, // AE VK_VOLUME_DOWN
426-
0, // AF VK_VOLUME_UP
427-
0, // B0 VK_MEDIA_NEXT_TRACK
428-
0, // B1 VK_MEDIA_PREV_TRACK
429-
0, // B2 VK_MEDIA_STOP
430-
0, // B3 VK_MEDIA_PLAY_PAUSE
431-
0, // B4 VK_LAUNCH_MAIL
432-
0, // B5 VK_LAUNCH_MEDIA_SELECT
433-
0, // B6 VK_LAUNCH_APP1
434-
0, // B7 VK_LAUNCH_APP2
435-
0,0, // B8,B9 -
436-
';', // BA VK_OEM_1
437-
'+', // BB VK_OEM_PLUS
438-
',', // BC VK_OEM_COMMA
439-
'-', // BD VK_OEM_MINUS
440-
'.', // BE VK_OEM_PERIOD
441-
'/', // BF VK_OEM_2
442-
'`', // C0 VK_OEM_3
443-
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // C1-D7 -
444-
0,0,0, // D8-DA -
445-
'[', // DB VK_OEM_4
446-
'\\', // DC VK_OEM_5
447-
']', // DD VK_OEM_6
448-
'\'', // DE VK_OEM_7
449-
};
450235

451-
#ifdef _WIN32
452-
int sys_main_c::KeyToVirtual(byte key)
453-
{
454-
if (key >= 32 && key <= 127) {
455-
return toupper(key);
456-
}
457-
for (int v = 0; v <= VK_OEM_7; v++) {
458-
if (sys_keyRemap[v] == key) {
459-
return v;
460-
}
461-
}
462-
return 0;
463-
}
464-
465-
byte sys_main_c::VirtualToKey(int virt)
236+
static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode)
466237
{
467-
if (virt >= 0 && virt <= VK_OEM_7) {
468-
return sys_keyRemap[virt];
469-
} else {
470-
return 0;
238+
#if GLFW_HAS_GET_KEY_NAME
239+
// GLFW 3.1+ attempts to "untranslate" keys, which goes the opposite of what every other framework does, making using lettered shortcuts difficult.
240+
// (It had reasons to do so: namely GLFW is/was more likely to be used for WASD-type game controls rather than lettered shortcuts, but IHMO the 3.1 change could have been done differently)
241+
// See https://github.com/glfw/glfw/issues/1502 for details.
242+
// Adding a workaround to undo this (so our keys are translated->untranslated->translated, likely a lossy process).
243+
// This won't cover edge cases but this is at least going to cover common cases.
244+
if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_EQUAL)
245+
return key;
246+
const char* key_name = glfwGetKeyName(key, scancode);
247+
if (key_name && key_name[0] != 0 && key_name[1] == 0)
248+
{
249+
const char char_names[] = "`-=[]\\,;\'./";
250+
const int char_keys[] = { GLFW_KEY_GRAVE_ACCENT, GLFW_KEY_MINUS, GLFW_KEY_EQUAL, GLFW_KEY_LEFT_BRACKET, GLFW_KEY_RIGHT_BRACKET, GLFW_KEY_BACKSLASH, GLFW_KEY_COMMA, GLFW_KEY_SEMICOLON, GLFW_KEY_APOSTROPHE, GLFW_KEY_PERIOD, GLFW_KEY_SLASH, 0 };
251+
if (key_name[0] >= '0' && key_name[0] <= '9') { key = GLFW_KEY_0 + (key_name[0] - '0'); }
252+
else if (key_name[0] >= 'A' && key_name[0] <= 'Z') { key = GLFW_KEY_A + (key_name[0] - 'A'); }
253+
else if (key_name[0] >= 'a' && key_name[0] <= 'z') { key = GLFW_KEY_A + (key_name[0] - 'a'); }
254+
else if (const char* p = strchr(char_names, key_name[0])) { key = char_keys[p - char_names]; }
471255
}
472-
}
473256
#endif
257+
return key;
258+
}
474259

475-
byte sys_main_c::GlfwKeyToKey(int key) {
260+
byte sys_main_c::GlfwKeyToKey(int key, int scancode) {
476261
static std::map<int, byte> s_lookup = {
477262
{GLFW_KEY_BACKSPACE, KEY_BACK},
478263
{GLFW_KEY_TAB, KEY_TAB},
@@ -511,8 +296,14 @@ byte sys_main_c::GlfwKeyToKey(int key) {
511296
{GLFW_KEY_BACKSLASH, '\\'},
512297
{GLFW_KEY_RIGHT_BRACKET, ']'},
513298
{GLFW_KEY_APOSTROPHE, '\''},
299+
{GLFW_KEY_KP_0, '0'},
300+
{GLFW_KEY_KP_SUBTRACT, '-'},
301+
{GLFW_KEY_KP_ADD, '+'},
302+
{GLFW_KEY_KP_ENTER, KEY_RETURN},
514303
};
515304

305+
key = ImGui_ImplGlfw_TranslateUntranslatedKey(key, scancode);
306+
516307
auto I = s_lookup.find(key);
517308
if (I != s_lookup.end()) {
518309
return I->second;

engine/system/win/sys_video.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ int sys_video_c::Apply(sys_vidSet_s* set)
520520
if (ImGui::GetIO().WantCaptureKeyboard) {
521521
return;
522522
}
523-
if (byte k = sys->GlfwKeyToKey(key)) {
523+
if (byte k = sys->GlfwKeyToKey(key, scancode)) {
524524
bool is_down = action == GLFW_PRESS || action == GLFW_REPEAT;
525525
sys->heldKeyState[k] = is_down;
526526
sys->core->KeyEvent(k, is_down ? KE_KEYDOWN : KE_KEYUP);

0 commit comments

Comments
 (0)