Gamepad.lua 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. local events = require("Engine.events")
  2. local coreg = require("Engine.coreg")
  3. return function(config) --A function that creates a new Gamepad peripheral.
  4. local GP, yGP, devkit = {}, {}
  5. local CPUKit = config.CPUKit
  6. if not CPUKit then error("The gamepad peripheral can't work without the CPUKit passed !") end
  7. if love.filesystem.getInfo("GamepadMapping.txt","file") then
  8. love.joystick.loadGamepadMappings("GamepadMapping.txt")
  9. end
  10. local debug = config.debug
  11. local deadzone = config.deadzone or 0.49
  12. local axisMemory = {}
  13. local mappingState = false --Is joystick -> gamepad mapping mode active ?
  14. local alreadyMapped = {}
  15. local buttonsids = { "leftx","lefty","dpleft","dpright","dpup","dpdown","a","b","start" }
  16. local map = {
  17. ["dpleft"] = 1,
  18. ["dpright"] = 2,
  19. ["dpup"] = 3,
  20. ["dpdown"] = 4,
  21. ["a"] = 5,
  22. ["b"] = 6,
  23. ["start"] = 7
  24. }
  25. events:register("love:joystickadded",function(joystick)
  26. print("Joystick Connected ! Gamepad: "..tostring(joystick:isGamepad())..", ID: "..joystick:getID()..", GUID: "..joystick:getGUID()..", Name: "..joystick:getName())
  27. end)
  28. events:register("love:gamepadpressed",function(joystick, button)
  29. if mappingState then return end
  30. local id = joystick:getID()
  31. if not map[button] then return end --The button doesn't have a binding.
  32. CPUKit.triggerEvent("gamepad",true,map[button],id)
  33. end)
  34. events:register("love:gamepadreleased",function(joystick, button)
  35. if mappingState then return end
  36. local id = joystick:getID()
  37. if not map[button] then return end --The button doesn't have a binding.
  38. CPUKit.triggerEvent("gamepad",false,map[button],id)
  39. end)
  40. events:register("love:gamepadaxis",function(joystick, axis)
  41. if mappingState then return end
  42. local id = joystick:getID()
  43. if not axisMemory[id] then axisMemory[id] = {false,false,false,false} end
  44. local memory = axisMemory[id]
  45. local value = joystick:getGamepadAxis(axis)
  46. if axis == "leftx" then
  47. if math.abs(value) < deadzone then --Release both left and right
  48. if memory[1] then CPUKit.triggerEvent("gamepad",false,1,id); memory[1] = false end
  49. if memory[2] then CPUKit.triggerEvent("gamepad",false,2,id); memory[2] = false end
  50. return
  51. end
  52. if value < 0 then --Left
  53. if memory[2] then CPUKit.triggerEvent("gamepad",false,2,id); memory[2] = false end
  54. if not memory[1] then CPUKit.triggerEvent("gamepad",true,1,id); memory[1] = true end
  55. else --Right
  56. if memory[1] then CPUKit.triggerEvent("gamepad",false,1,id); memory[1] = false end
  57. if not memory[2] then CPUKit.triggerEvent("gamepad",true,2,id); memory[2] = true end
  58. end
  59. elseif axis == "lefty" then
  60. if math.abs(value) < deadzone then --Release both up and down
  61. if memory[3] then CPUKit.triggerEvent("gamepad",false,3,id); memory[3] = false end
  62. if memory[4] then CPUKit.triggerEvent("gamepad",false,4,id); memory[4] = false end
  63. return
  64. end
  65. if value < 0 then --Up
  66. if memory[4] then CPUKit.triggerEvent("gamepad",false,4,id); memory[4] = false end
  67. if not memory[3] then CPUKit.triggerEvent("gamepad",true,3,id); memory[3] = true end
  68. else --Down
  69. if memory[3] then CPUKit.triggerEvent("gamepad",false,3,id); memory[3] = false end
  70. if not memory[4] then CPUKit.triggerEvent("gamepad",true,4,id); memory[4] = true end
  71. end
  72. end
  73. end)
  74. function GP._GetGUID()
  75. mappingState = {mode="getGUID"}
  76. end
  77. function GP._MapButton(guid,bid)
  78. local axis = (bid < 3)
  79. if axis then
  80. mappingState = {mode="MapAxis",guid=guid,id=buttonsids[bid]}
  81. else
  82. mappingState = {mode="MapButton",guid=guid,id=buttonsids[bid]}
  83. end
  84. end
  85. function GP._CancelMapping()
  86. mappingState = false
  87. end
  88. function GP._SaveMap()
  89. return love.joystick.saveGamepadMappings("GamepadMapping.txt")
  90. end
  91. events:register("love:joystickpressed",function(joystick,button)
  92. if debug then print("Joystick pressed",button) end
  93. if not mappingState then return end
  94. if mappingState.mode == "getGUID" then
  95. mappingState = false
  96. CPUKit.triggerEvent("_gamepadmap",joystick:getGUID())
  97. elseif mappingState.mode == "MapButton" then
  98. local guid = joystick:getGUID()
  99. local bid = mappingState.id
  100. if not guid == mappingState.guid then return end --It's not the joystick we are mapping !
  101. mappingState = false
  102. CPUKit.triggerEvent("_gamepadmap",love.joystick.setGamepadMapping(guid,bid,"button",button))
  103. end
  104. end)
  105. events:register("love:joystickaxis",function(joystick,axis,value)
  106. if debug then print("Joystick axis",axis,value) end
  107. if not mappingState then return end
  108. if math.abs(value) < deadzone then return end
  109. if mappingState.mode == "getGUID" then
  110. mappingState = false
  111. coreg:resumeCoroutine(true,joystick:getGUID())
  112. elseif mappingState.mode == "MapAxis" then
  113. local guid = joystick:getGUID()
  114. local bid = mappingState.id
  115. if (not guid == mappingState.guid) or alreadyMapped[axis] then return end --It's not the joystick we are mapping !
  116. mappingState = false
  117. if bid == "leftx" then alreadyMapped[axis] = true else alreadyMapped = {} end
  118. CPUKit.triggerEvent("_gamepadmap",love.joystick.setGamepadMapping(guid,bid,"axis",axis))
  119. end
  120. end)
  121. events:register("love:joystickhat",function(joystick,hat,direction)
  122. if debug then print("Joystick hat",hat,direction) end
  123. if not mappingState then return end
  124. if direction == "c" or direction:len() > 1 then return end
  125. if mappingState.mode == "getGUID" then
  126. mappingState = false
  127. coreg:resumeCoroutine(true,joystick:getGUID())
  128. elseif mappingState.mode == "MapButton" then
  129. local guid = joystick:getGUID()
  130. local bid = mappingState.id
  131. if not guid == mappingState.guid then return end --It's not the joystick we are mapping !
  132. mappingState = false
  133. CPUKit.triggerEvent("_gamepadmap",love.joystick.setGamepadMapping(guid,bid,"hat",hat,direction))
  134. end
  135. end)
  136. return GP, yGP, devkit
  137. end