Ooops
October 24, 2021, 05:04:15

Author Topic: [bmx] Input Class/Lua Script by N [ 1+ years ago ]  (Read 734 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bmx] Input Class/Lua Script by N [ 1+ years ago ]
« on: June 29, 2017, 00:28:41 »
Title : Input Class/Lua Script
Author : N
Posted : 1+ years ago

Description : This is a small class and script for use with LuGI - although you could probably make it work without.

The script should be loaded after LuGI is initialized and the Input global is set, at which point this takes the global and hides it away in a table and provides a wrapper for it that handles more than just Key/MouseDown, but also allows you to hook functions to keys based on priority and the type of event they want to receive (whether it's when the key is pressed or release) and so on.


Code :
Code: BlitzMax
  1. ' input.bmx
  2. SuperStrict
  3.  
  4. Import LuGI.Core
  5.  
  6. Type Input {expose static}
  7.         Method l_KeyDown:Int(key:Int) {rename="KeyDown" bool}
  8.                 Return KeyDown(key)
  9.         End Method
  10.        
  11.         Method l_MouseDown:Int(button:Int) {rename="MouseDown" bool}
  12.                 Return MouseDown(button)
  13.         End Method
  14.        
  15.         Method l_MouseX:Int()
  16.                 Return MouseX()
  17.         End Method
  18.        
  19.         Method l_MouseY:Int()
  20.                 Return MouseY()
  21.         End Method
  22.        
  23.         Method l_MouseZ:Int()
  24.                 Return MouseZ()
  25.         End Method
  26.        
  27.         Method l_MouseXSpeed:Int()
  28.                 Return MouseXSpeed()
  29.         End Method
  30.        
  31.         Method l_MouseYSpeed:Int()
  32.                 Return MouseYSpeed()
  33.         End Method
  34.        
  35.         Method l_MouseZSpeed:Int()
  36.                 Return MouseZSpeed()
  37.         End Method
  38. End Type
  39.  
  40.  
  41.  
  42.  
  43. -- input.lua
  44. -- Borrowing values from the keycodes module
  45.  
  46. Mouse = {
  47.         Left = 1,
  48.         Right = 2,
  49.         Middle = 3,
  50. }
  51.  
  52. Modifier = {
  53.         Shift = 1,
  54.         Control = 2,
  55.         Option = 4,
  56.         System = 8,
  57.         LeftMouse = 16,
  58.         RightMouse = 32,
  59.         MiddleMouse = 64,
  60. }
  61.  
  62. Key = {
  63.         Backspace = 8,
  64.         Tab = 9,
  65.         Clear = 12,
  66.         Return = 13, Enter = 13,
  67.         Escape = 27,
  68.         Space = 32,
  69.         PageUp = 33,
  70.         PageDown = 34,
  71.         End = 35,
  72.         Home = 36,
  73.         Left = 37,
  74.         Up = 38,
  75.         Right = 39,
  76.         Down = 40,
  77.         Select = 41,
  78.         Print = 42,
  79.         Execute = 43,
  80.         PrintScreen = 44,
  81.         Insert = 45,
  82.         Delete = 46,
  83.         ["0"] = 48,
  84.         ["1"] = 49,
  85.         ["2"] = 50,
  86.         ["3"] = 51,
  87.         ["4"] = 52,
  88.         ["5"] = 53,
  89.         ["6"] = 54,
  90.         ["7"] = 55,
  91.         ["8"] = 56,
  92.         ["9"] = 57,
  93.         A = 65, a = 65,
  94.         B = 66, b = 66,
  95.         C = 67, c = 67,
  96.         D = 68, d = 68,
  97.         E = 69, e = 69,
  98.         F = 70, f = 70,
  99.         G = 71, g = 71,
  100.         H = 72, h = 72,
  101.         I = 73, i = 73,
  102.         J = 74, j = 74,
  103.         K = 75, k = 75,
  104.         L = 76, l = 76,
  105.         M = 77, m = 77,
  106.         N = 78, n = 78,
  107.         O = 79, o = 79,
  108.         P = 80, p = 80,
  109.         Q = 81, q = 81,
  110.         R = 82, r = 82,
  111.         S = 83, s = 83,
  112.         T = 84, t = 84,
  113.         U = 85, u = 85,
  114.         V = 86, v = 86,
  115.         W = 87, w = 87,
  116.         X = 88, x = 88,
  117.         Y = 89, y = 89,
  118.         Z = 90, z = 90,
  119.         Numpad0 = 96,
  120.         Numpad1 = 97,
  121.         Numpad2 = 98,
  122.         Numpad3 = 99,
  123.         Numpad4 = 100,
  124.         Numpad5 = 101,
  125.         Numpad6 = 102,
  126.         Numpad7 = 103,
  127.         Numpad8 = 104,
  128.         Numpad9 = 105,
  129.         NumpadMultiply = 106,
  130.         NumpadPlus = 107,
  131.         NumpadMinus = 109,
  132.         NumpadPeriod = 110,
  133.         NumpadSlash = 111,
  134.         F1 = 112,
  135.         F2 = 113,
  136.         F3 = 114,
  137.         F4 = 115,
  138.         F5 = 116,
  139.         F6 = 117,
  140.         F7 = 118,
  141.         F8 = 119,
  142.         F9 = 120,
  143.         F10 = 121,
  144.         F11 = 122,
  145.         F12 = 123,
  146.         Tilde = 192,
  147.         Minus = 189,
  148.         Equals = 187,
  149.         OpenBracket = 219,
  150.         CloseBracket = 221,
  151.         Backslash = 226,
  152.         Semicolon = 186,
  153.         Quotes = 222,
  154.         Comma = 188,
  155.         Period = 190,
  156.         Slash = 191,
  157.         LeftShift = 160,
  158.         RightShift = 161,
  159.         LeftControl = 162,
  160.         RightControl = 163,
  161.         LeftOption = 164,
  162.         RightOption = 165,
  163.         LeftSystem = 91,
  164.         RightSystem = 92,
  165.         -- typing this wasn't fun.  should've used a regex.
  166. }
  167.  
  168.  
  169. local function _stateCheck(self, current_name, previous_name, comp)
  170.         return function(self, ...)
  171.                 buttons = {...}
  172.                
  173.                 for key,button in next, buttons, nil do
  174.                         buttons[button] = comp(self[current_name][button], self[previous_name][button])
  175.                 end
  176.                
  177.                 return unpack(buttons)
  178.         end
  179. end
  180.  
  181. local function _downState(self, current_name, previous_name)
  182.         return _stateCheck(self, current_name, previous_name, function(c,p) return c end)
  183. end
  184.  
  185. local function _hitState(self, current_name, previous_name)
  186.         return _stateCheck(self, current_name, previous_name, function(c,p) return (c and not p) end)
  187. end
  188.  
  189. local function _upState(self, current_name, previous_name)
  190.         return _stateCheck(self, current_name, previous_name, function(c,p) return (not c and p) end)
  191. end
  192.  
  193. local function _bind(name)
  194.         return function(self)
  195.                 return self._input[name]()
  196.         end
  197. end
  198.  
  199. _G.Input = {
  200.         _input = (type(Input) == "table" and Input._input) or Input,            -- store old Input singleton object (bmx) and wrap it
  201.         keys_previous = {},
  202.         keys_current = {},
  203.         mouse_current = {},
  204.         mouse_previous = {},
  205.         bindings_keys = {
  206.                 --[[
  207.                 key = {
  208.                         closure = function(key, depressed) ... end -> handled
  209.                         onPress = true|false
  210.                         onRelease = true|false
  211.                         priority = number
  212.                 }
  213.                 ]]
  214.         },
  215.         bindings_mouse = { --[[ same model as above ]] },
  216.  
  217.         -- Get key state
  218.  
  219.         KeyDown = _downState(self, "keys_current", "keys_previous"),
  220.         KeyHit = _hitState(self, "keys_current", "keys_previous"),
  221.         KeyUp = _upState(self, "keys_current", "keys_previous"),
  222.  
  223.         MouseDown = _downState(self, "mouse_current", "mouse_previous"),
  224.         MouseHit = _hitState(self, "mouse_current", "mouse_previous"),
  225.         MouseUp = _upState(self, "mouse_current", "mouse_previous"),
  226.  
  227.         MousePosition = function(self) return self._input:MouseX(), self._input:MouseY(), self._input:MouseZ() end,
  228.         MouseSpeed = function(self) return self._input:MouseXSpeed(), self._input:MouseYSpeed(), self._input:MouseZSpeed() end,
  229.         MouseX = _bind("MouseX"), MouseY = _bind("MouseY"), MouseZ = _bind("MouseZ"),
  230.         MouseXSpeed = _bind("MouseXSpeed"), MouseYSpeed = _bind("MouseYSpeed"), MouseZSpeed = _bind("MouseZSpeed"),
  231.  
  232.  
  233.         -- Update
  234.  
  235.         _runBindings = function(self, binder, current, previous)
  236.                 for k,v in next, current, nil do
  237.                         if v ~= (previous[k] or false) then
  238.                                 bindings = binder[k]
  239.                                 if bindings then
  240.                                         for bk, binding in next, bindings, nil do
  241.                                                 if ((v and binding.onPress) or (not v and binding.onRelease)) and binding.closure(k, v) then
  242.                                                         break
  243.                                                 end
  244.                                         end
  245.                                 end
  246.                         end
  247.                 end
  248.         end,
  249.  
  250.         _updateState = function(self, states, buttons, buttonStatus)
  251.                 for k,button in next, buttons, nil do
  252.                         states[button] = buttonStatus(self._input, button)
  253.                 end
  254.         end,
  255.  
  256.         Update = function(self)
  257.                 do local t = self.keys_previous
  258.                         self.keys_previous = self.keys_current
  259.                         self.keys_current = t
  260.                         t = self.mouse_current
  261.                         self.mouse_current = self.mouse_previous
  262.                         self.mouse_previous = t
  263.                 end
  264.                
  265.                 self:_updateState(self.keys_current, Key, self._input.KeyDown)
  266.                 self:_updateState(self.mouse_current, Mouse, self._input.MouseDown)
  267.                
  268.                 self:_runBindings(self.bindings_mouse, self.mouse_current, self.mouse_previous)
  269.                 self:_runBindings(self.bindings_keys, self.keys_current, self.keys_previous)
  270.         end,
  271.  
  272.  
  273.         -- Bindings
  274.  
  275.         _setBinding = function(self, binder, button, binding, onPress, onRelease, priority)
  276.                 local old_binding = binder[button]
  277.                
  278.                 priority = priority or 0
  279.                
  280.                 bindings = binder[button]
  281.                 if not bindings then
  282.                         binder[button] = {}
  283.                         bindings = binder[button]
  284.                 end
  285.                
  286.                 if binding and (onPress or onRelease) then
  287.                         table.insert(bindings, {
  288.                                 closure = binding,
  289.                                 ["onPress"] = onPress,
  290.                                 ["onRelease"] = onRelease,
  291.                                 ["priority"] = priority
  292.                         })
  293.                         table.sort(bindings,
  294.                                 function(left, right) return left.priority > right.priority end)
  295.                 end
  296.        
  297.                 return old_binding and unpack(old_binding)
  298.         end,
  299.  
  300.         _removeBinding = function(self, binder, button, binding)
  301.                 bindings = binder[button]
  302.                 if bindings then
  303.                         for i,v in ipairs(bindings) do
  304.                                 if v.closure == binding then
  305.                                         table.remove(bindings, i)
  306.                                         return unpack(v)
  307.                                 end
  308.                         end
  309.                 end
  310.         end,
  311.  
  312.         AddKeyBinding = function(self, key, binding, onPress, onRelease, priority)
  313.                 return self:_setBinding(self.bindings_keys, key, binding, onPress, onRelease, priority)
  314.         end,
  315.  
  316.         RemoveKeyBinding = function(self, key, binding)
  317.                 return self:_removeBinding(self.bindings_keys, key, binding)
  318.         end,
  319.        
  320.         ClearKeyBindings = function(self, key)
  321.                 self.bindings_keys[key] = {}
  322.         end,
  323.  
  324.         AddMouseBinding = function(self, button, binding, onPress, onRelease, priority)
  325.                 return self:_setBinding(self.bindings_mouse, button, binding, onPress, onRelease, priority)
  326.         end,
  327.  
  328.         RemoveMouseBinding = function(self, button, binding)
  329.                 return self:_removeBinding(self.bindings_mouse, button, binding)
  330.         end,
  331.        
  332.         ClearMouseBindings = function(self, button)
  333.                 self.bindings_mouse[button] = {}
  334.         end,
  335. }


Comments :


_Skully(Posted 1+ years ago)

 I say again.. Yoink!Thanks Nilium


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal