input.lua 8.2 KB

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