fix(input): keys are physical positions on every layout; Input.key_label names them
The Windows runtime keyed the held set by the character MapVirtualKeyA gave a virtual key, so a game's WASD belonged to whatever the active layout put there, and with an input method on every letter arrived as VK_PROCESSKEY. The typing block is now read from the scancode (the arrows, numpad and F-keys still by virtual key); macOS reads keyCode the same way. Input.key_label(key) names a key in the player's own layout (Windows) or as its US character elsewhere. Verified on Windows with SendInput into a live window: VK_Z carrying W's scancode holds 'w', VK_PROCESSKEY carrying A's holds 'a', Caps Lock changes nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
2a2f463d5b
commit
619476ffed
14 changed files with 60552 additions and 60168 deletions
|
|
@ -372,6 +372,46 @@ function input_key_down(k: int) -> bool { in_init(); return in_bit_get(in_h
|
|||
function input_key_pressed(k: int) -> bool { in_init(); return in_bit_get(in_held, k) and (not in_bit_get(in_prev, k)) }
|
||||
function input_key_released(k: int) -> bool { in_init(); return (not in_bit_get(in_held, k)) and in_bit_get(in_prev, k) }
|
||||
|
||||
# The name to show a player for key code `k`. A letter, digit or punctuation code is a
|
||||
# PHYSICAL key - the one that types it on a US layout - so the name is what the player's
|
||||
# own layout types there: 'w' reads "W" on QWERTY and "Z" on AZERTY, and a binding
|
||||
# shown as "W" is never a key the player cannot find. Named keys and the arrows get words.
|
||||
# Headless, and on a platform that cannot ask the layout, it is the US character.
|
||||
function input_key_label(k: int) -> string {
|
||||
if k == 32 { return "Space" }
|
||||
if k == 10 { return "Enter" }
|
||||
if k == 27 { return "Esc" }
|
||||
if k == 9 { return "Tab" }
|
||||
if k == 8 { return "Backspace" }
|
||||
if k == 16 { return "Shift" }
|
||||
if k == 17 { return "Ctrl" }
|
||||
if k == 18 { return "Alt" }
|
||||
if k == 128 { return "Up" }
|
||||
if k == 129 { return "Down" }
|
||||
if k == 130 { return "Left" }
|
||||
if k == 131 { return "Right" }
|
||||
var c = 0
|
||||
if is_windowed() { c = win_key_char(k) }
|
||||
if c <= 0 and k > 32 and k < 127 {
|
||||
c = k
|
||||
if c >= 97 and c <= 122 { c = c - 32 }
|
||||
}
|
||||
if c <= 0 { return "" }
|
||||
return in_utf8(c)
|
||||
}
|
||||
# one code point as a UTF-8 string
|
||||
function in_utf8(c: int) -> string {
|
||||
let out = bytes(5)
|
||||
var n = 0
|
||||
if c < 128 { out[0] = c; n = 1 }
|
||||
else if c < 2048 { out[0] = 192 | (c >> 6); out[1] = 128 | (c & 63); n = 2 }
|
||||
else if c < 65536 { out[0] = 224 | (c >> 12); out[1] = 128 | ((c >> 6) & 63); out[2] = 128 | (c & 63); n = 3 }
|
||||
else { out[0] = 240 | (c >> 18); out[1] = 128 | ((c >> 12) & 63); out[2] = 128 | ((c >> 6) & 63); out[3] = 128 | (c & 63); n = 4 }
|
||||
out[n] = 0
|
||||
let s: string = out
|
||||
return s
|
||||
}
|
||||
|
||||
# inject a held key (AI, tutorial, testing, network) — persists until released.
|
||||
function input_press(k: int) -> void { in_init(); in_bit_set(in_sim, k, true) }
|
||||
function input_release(k: int) -> void { in_init(); in_bit_set(in_sim, k, false) }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue