input.lua 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. local Commands={["instances"]={}}
  2. function Commands.new(pmtlist)
  3. local devices={["keyboard"]={},["gamepad"]={},["touchscreen"]={},["mouse"]={}}
  4. local istouch,isgamepad,ismouse,iskeyboard=pmtlist.touchscreen or false,pmtlist.gamepad or true,pmtlist.mouse or false,pmtlist.keyboard or true
  5. local diagonals,longkeys=pmtlist.diagonals or true,pmtlist.longkeys or true-- Lists desactivate everything
  6. local state,timer=false,0
  7. local keypressed,keyreleased,keylist,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. keylist={}
  106. 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(keylonglist,devices.keyboard[i].cmd)
  114. end
  115. if 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(keylist,b)
  126. table.remove(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(keylist,a[1])
  132. else
  133. table.insert(keylist,devices.keyboard[i].cmd)
  134. end
  135. else
  136. table.insert(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(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(keylist) do
  152. if key==keylist[i] then
  153. return true
  154. end
  155. end
  156. return false
  157. end
  158. end
  159. function devices.update(dt)
  160. if iskeyboard then
  161. function love.keypressed(key,scancode)
  162. keypressed=devices.keylink(scancode)
  163. state=true
  164. end
  165. function love.keyreleased(key,scancode)
  166. keyreleased=devices.keylink(scancode)
  167. state=false
  168. timer=0
  169. end
  170. -- To avoid workload for analyzing keyboard
  171. if keypressed~="" or #keylist~=0 then
  172. devices.list()
  173. if state and longkeys then
  174. timer=timer+7.5*dt
  175. if timer>3 then
  176. devices.list("timed")
  177. timer=0
  178. end
  179. end
  180. end
  181. end
  182. keypressed,keyreleased="",""
  183. end
  184. return devices
  185. end
  186. return Commands