123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- local ffi = assert(type(jit) == 'table' and -- Only run if we have LuaJIT
- lovr.system.getOS() ~= 'Android' and lovr.system.getOS() ~= 'Web' and -- and also GLFW
- require 'ffi', "lovr-keyboard cannot run on this platform")
- local C = ffi.os == 'Windows' and ffi.load('glfw3') or ffi.C
- ffi.cdef [[
- typedef struct GLFWwindow GLFWwindow;
- typedef void(*GLFWkeyfun)(GLFWwindow*, int, int, int, int);
- typedef void(*GLFWcharfun)(GLFWwindow*, unsigned int);
- GLFWwindow* os_get_glfw_window(void);
- int glfwGetKey(GLFWwindow* window, int key);
- GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun callback);
- GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun callback);
- ]]
- local window = ffi.C.os_get_glfw_window()
- local keymap = {
- ['space'] = { 32, 0, 0 },
- ['\''] = { 39, 0, 0 },
- [','] = { 44, 0, 0 },
- ['-'] = { 45, 0, 0 },
- ['.'] = { 46, 0, 0 },
- ['/'] = { 47, 0, 0 },
- ['0'] = { 48, 0, 0 },
- ['1'] = { 49, 0, 0 },
- ['2'] = { 50, 0, 0 },
- ['3'] = { 51, 0, 0 },
- ['4'] = { 52, 0, 0 },
- ['5'] = { 53, 0, 0 },
- ['6'] = { 54, 0, 0 },
- ['7'] = { 55, 0, 0 },
- ['8'] = { 56, 0, 0 },
- ['9'] = { 57, 0, 0 },
- [';'] = { 59, 0, 0 },
- ['='] = { 61, 0, 0 },
- ['a'] = { 65, 0, 0 },
- ['b'] = { 66, 0, 0 },
- ['c'] = { 67, 0, 0 },
- ['d'] = { 68, 0, 0 },
- ['e'] = { 69, 0, 0 },
- ['f'] = { 70, 0, 0 },
- ['g'] = { 71, 0, 0 },
- ['h'] = { 72, 0, 0 },
- ['i'] = { 73, 0, 0 },
- ['j'] = { 74, 0, 0 },
- ['k'] = { 75, 0, 0 },
- ['l'] = { 76, 0, 0 },
- ['m'] = { 77, 0, 0 },
- ['n'] = { 78, 0, 0 },
- ['o'] = { 79, 0, 0 },
- ['p'] = { 80, 0, 0 },
- ['q'] = { 81, 0, 0 },
- ['r'] = { 82, 0, 0 },
- ['s'] = { 83, 0, 0 },
- ['t'] = { 84, 0, 0 },
- ['u'] = { 85, 0, 0 },
- ['v'] = { 86, 0, 0 },
- ['w'] = { 87, 0, 0 },
- ['x'] = { 88, 0, 0 },
- ['y'] = { 89, 0, 0 },
- ['z'] = { 90, 0, 0 },
- ['['] = { 91, 0, 0 },
- ['\\'] = { 92, 0, 0 },
- [']'] = { 93, 0, 0 },
- ['`'] = { 96, 0, 0 },
- ['escape'] = { 256, 0, 0 },
- ['return'] = { 257, 0, 0 },
- ['enter'] = { 257, 0, 0 },
- ['tab'] = { 258, 0, 0 },
- ['backspace'] = { 259, 0, 0 },
- ['insert'] = { 260, 0, 0 },
- ['delete'] = { 261, 0, 0 },
- ['right'] = { 262, 0, 0 },
- ['left'] = { 263, 0, 0 },
- ['down'] = { 264, 0, 0 },
- ['up'] = { 265, 0, 0 },
- ['pageup'] = { 266, 0, 0 },
- ['pagedown'] = { 267, 0, 0 },
- ['home'] = { 268, 0, 0 },
- ['end'] = { 269, 0, 0 },
- ['capslock'] = { 280, 0, 0 },
- ['scrolllock'] = { 281, 0, 0 },
- ['numlock'] = { 282, 0, 0 },
- ['printscreen'] = { 283, 0, 0 },
- ['pause'] = { 284, 0, 0 },
- ['f1'] = { 290, 0, 0 },
- ['f2'] = { 291, 0, 0 },
- ['f3'] = { 292, 0, 0 },
- ['f4'] = { 293, 0, 0 },
- ['f5'] = { 294, 0, 0 },
- ['f6'] = { 295, 0, 0 },
- ['f7'] = { 296, 0, 0 },
- ['f8'] = { 297, 0, 0 },
- ['f9'] = { 298, 0, 0 },
- ['f10'] = { 299, 0, 0 },
- ['f11'] = { 300, 0, 0 },
- ['f12'] = { 301, 0, 0 },
- ['kp0'] = { 320, 0, 0 },
- ['kp1'] = { 321, 0, 0 },
- ['kp2'] = { 322, 0, 0 },
- ['kp3'] = { 323, 0, 0 },
- ['kp4'] = { 324, 0, 0 },
- ['kp5'] = { 325, 0, 0 },
- ['kp6'] = { 326, 0, 0 },
- ['kp7'] = { 327, 0, 0 },
- ['kp8'] = { 328, 0, 0 },
- ['kp9'] = { 329, 0, 0 },
- ['kp.'] = { 330, 0, 0 },
- ['kp/'] = { 331, 0, 0 },
- ['kp*'] = { 332, 0, 0 },
- ['kp-'] = { 333, 0, 0 },
- ['kp+'] = { 334, 0, 0 },
- ['kpenter'] = { 335, 0, 0 },
- ['kp='] = { 336, 0, 0 },
- ['lshift'] = { 340, 0, 0 },
- ['lctrl'] = { 341, 0, 0 },
- ['lalt'] = { 342, 0, 0 },
- ['lgui'] = { 343, 0, 0 },
- ['rshift'] = { 344, 0, 0 },
- ['rctrl'] = { 345, 0, 0 },
- ['ralt'] = { 346, 0, 0 },
- ['rgui'] = { 347, 0, 0 },
- ['menu'] = { 348, 0, 0 }
- }
- local reverse = {}
- for k, v in pairs(keymap) do
- local keycode = v[1]
- reverse[keycode] = k
- end
- for k, v in pairs(reverse) do
- keymap[k] = v
- end
- local keyboard = {}
- function keyboard.isDown(key, ...)
- if not key then return false end
- local keycode = keymap[key][1]
- assert(keycode and type(keycode) == 'number', 'Unknown key: ' .. key)
- return C.glfwGetKey(window, keycode) == 1 or keyboard.isDown(...)
- end
- function keyboard.wasPressed(key, ...)
- if not key then return false end
- local keycode = keymap[key][1]
- assert(keycode and type(keycode) == 'number', 'Unknown key: ' .. key)
- local pressed = false
- keymap[key][3] = C.glfwGetKey(window, keycode)
- if keymap[key][2] == 0 and keymap[key][3] == 1 then
- pressed = true
- else
- pressed = false
- end
- keymap[key][2] = keymap[key][3]
- return pressed
- end
- function keyboard.wasReleased(key, ...)
- if not key then return false end
- local keycode = keymap[key][1]
- assert(keycode and type(keycode) == 'number', 'Unknown key: ' .. key)
- local released = false
- keymap[key][3] = C.glfwGetKey(window, keycode)
- if keymap[key][2] == 1 and keymap[key][3] == 0 then
- released = true
- else
- released = false
- end
- keymap[key][2] = keymap[key][3]
- return released
- end
- C.glfwSetKeyCallback(window, function(window, key, scancode, action, mods)
- if action ~= 2 and keymap[key] then
- lovr.event.push(action > 0 and 'keypressed' or 'keyreleased', keymap[key])
- end
- end)
- C.glfwSetCharCallback(window, function(window, char)
- lovr.event.push('textinput', string.char(char))
- end)
- return keyboard
|