input.lua 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. -- Should be lighter than V1
  2. local Commands={}
  3. -- Provided global vars
  4. Global={["Key"]={}}
  5. Global.Key.pressed=""
  6. Global.Key.released=""
  7. Global.Key.list={}
  8. Global.Key.longlist={} -- For longpresses
  9. function Commands.new(pmtlist)
  10. local devices={["keyboard"]={},["gamepad"]={},["touchscreen"]={},["mouse"]={}}
  11. local istouch,isgamepad,ismouse,iskeyboard=pmtlist.touchscreen or false,pmtlist.gamepad or true,pmtlist.mouse or false,pmtlist.keyboard or true
  12. local diagonals,longkeys,lists=pmtlist.diagonals or true,pmtlist.longkeys or true,pmtlist.lists or true -- Lists desactivate everything
  13. local state,timer=false,0
  14. function devices.modifyperms(newpmtlist)
  15. istouch,isgamepad=newpmtlist.touchscreen or istouch,newpmtlist.gamepad or isgamepad
  16. ismouse,iskeyboard=newpmtlist.mouse or ismouse,newpmtlist.keyboard or iskeyboard
  17. diagonals,longkeys,lists=newpmtlist.diagonals,newpmtlist.longkeys,newpmtlist.lists or lists
  18. end
  19. function devices.mapping(dv,method,arg)
  20. -- Add a key
  21. if method=="add" then
  22. if dv=="keyboard" then
  23. --[[ example : key={syml={"w","up"},cmd="up",locked=false,type="movement"}
  24. cmd is the real key, syml is the symslink,
  25. locked if bindable, only for first key in index of cmd, other are locked
  26. cmd and syml should be one of those keys : https://love2d.org/wiki/Scancode
  27. The primordial type is "movement", good for diagonals.
  28. Structure of the key is different when added--]]
  29. for o=1,#arg.syml do
  30. devices.keyboard[arg.syml[o]]=arg
  31. if o>1 then
  32. devices.keyboard[arg.syml[o]].locked=true
  33. end
  34. end
  35. -- Call those keys with number index, e.g foo[x]
  36. elseif dv=="gamepad" then
  37. end
  38. -- Bind or swap a key, a table with the input and the target is awaited ({input="i",target="t"}) Still unchecked for bugs
  39. elseif method=="bind" then
  40. if dv=="keyboard" then
  41. local a,b
  42. for i in pairs(devices.keyboard) do
  43. if devices.keyboard[i].syml[1]==arg.input and devices.keyboard[i].locked then
  44. return -1
  45. elseif devices.keyboard[i].syml[1]==arg.target and devices.keyboard[i].locked then
  46. return -1
  47. end
  48. for o in pairs(devices.keyboard[i].syml) do
  49. -- You can't bind secondary keys
  50. if devices.keyboard[i].syml[o]==arg.input and o>1 then
  51. return -1
  52. elseif devices.keyboard[i].syml[o]==arg.input then
  53. a={i,o}
  54. elseif devices.keyboard[i].syml[o]==arg.target and o>1 then
  55. return -1
  56. elseif devices.keyboard[i].syml[o]==arg.target then
  57. b={i,o}
  58. end
  59. end
  60. end
  61. if a then
  62. if b then
  63. -- Swap keys
  64. devices.keyboard[a[1]].syml[a[2]],devices.keyboard[b[1]].syml[b[2]]=devices.keyboard[b[1]].syml[b[2]],devices.keyboard[a[1]].syml[a[2]]
  65. return 1
  66. end
  67. devices.keyboard[a[1]].syml[a[2]]=arg.target
  68. return 1
  69. end
  70. return -1
  71. elseif dv=="gamepad" then
  72. end
  73. -- Export mapping to a file, this time, arg is a string pointing to a file
  74. elseif method=="export" then
  75. if dv=="keyboard" then
  76. File.ectotoml(devices.keyboard,arg)
  77. elseif dv=="gamepad" then
  78. end
  79. -- Import the mapping of a file
  80. elseif method=="import" then
  81. if dv=="keyboard" then
  82. local a=File.dcfromtoml(arg)
  83. -- There can't be integers in toml. Therefore, they are all strings and needed to be converted
  84. for i in pairs(a) do
  85. for o in pairs(a[i]) do
  86. -- foo["x"] becomes foo[x]
  87. devices.keyboard[tonumber(i)]=a[i]
  88. end
  89. end
  90. elseif dv=="gamepad" then
  91. end
  92. end
  93. end
  94. -- Redirect to real key
  95. function devices.keylink(key)
  96. for i in pairs(devices.keyboard) do
  97. for o in pairs(devices.keyboard[i].syml) do
  98. if devices.keyboard[i].syml[o]==key then
  99. return devices.keyboard[i].cmd
  100. end
  101. end
  102. end
  103. end
  104. -- List all actives keys in lists
  105. function devices.list(listn) -- Has a complexity of O(n^2)
  106. Global.Key.list={}
  107. Global.Key.longlist={}
  108. local dict={"up","right","down","left","up"}
  109. local a,b={}
  110. for i in pairs(devices.keyboard) do
  111. for o in pairs(devices.keyboard[i].syml) do
  112. if love.keyboard.isScancodeDown(devices.keyboard[i].syml[o]) then
  113. if listn=="timed" then
  114. table.insert(Global.Key.longlist,devices.keyboard[i].cmd)
  115. end
  116. if diagonals then
  117. if devices.keyboard[i].type=="movement" then
  118. table.insert(a,devices.keyboard[i].cmd)
  119. if #a<2 then
  120. b=a[1].."-"..a[1]
  121. else
  122. b=a[1].."-"..a[2]
  123. end
  124. for n=1,4 do
  125. if b==dict[n].."-"..dict[n+1] or b==dict[n+1].."-"..dict[n] then
  126. table.insert(Global.Key.list,b)
  127. table.remove(Global.Key.list,1)
  128. -- up-right, right-down, down-left or left-up
  129. end
  130. end
  131. -- If it failed, normal moves
  132. table.insert(Global.Key.list,a[1])
  133. else
  134. table.insert(Global.Key.list,devices.keyboard[i].cmd)
  135. end
  136. else
  137. table.insert(Global.Key.list,devices.keyboard[i].cmd)
  138. end
  139. end
  140. end
  141. end
  142. end
  143. function devices.detect(key,arg) -- O(n)
  144. if arg=="timed" then
  145. for i in pairs(Global.Key.list) do
  146. if key==Global.Key.longlist[i] then
  147. return true
  148. end
  149. end
  150. return false
  151. else
  152. for i in pairs(Global.Key.list) do
  153. if key==Global.Key.list[i] then
  154. return true
  155. end
  156. end
  157. return false
  158. end
  159. end
  160. function devices.update(dt)
  161. if iskeyboard then
  162. function love.keypressed(key,scancode)
  163. Global.Key.pressed=devices.keylink(scancode)
  164. state=true
  165. end
  166. function love.keyreleased(key,scancode)
  167. Global.Key.released=devices.keylink(scancode)
  168. state=false
  169. timer=0
  170. end
  171. if lists then
  172. -- To avoid workload for analyzing keyboard
  173. if Global.Key.pressed~="" or #Global.Key.list~=0 then
  174. devices.list()
  175. if state and longkeys then
  176. timer=timer+7.5*dt
  177. if timer>3 then
  178. devices.list("timed")
  179. timer=0
  180. end
  181. end
  182. end
  183. end
  184. end
  185. Global.Key.pressed,Global.Key.released="",""
  186. end
  187. return devices
  188. end
  189. return Commands