[SOLVED] Gamepad mapping

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
cloudfrog
Prole
Posts: 8
Joined: Mon Feb 21, 2022 8:31 am

[SOLVED] Gamepad mapping

Post by cloudfrog »

I am using two joysticks. The first one works perfectly, but the second I'm not having any luck (JOY2 / PS3USB) below.

Using jstest outside of the game I can confirm both joysticks work fine. Buttons are mapped the same as well. But in love, i can't seem to get anything to work besides recognizing that it exists.
I tried to figure out get/set GamepadMapping, but not making any progress. I even tried "get" from one joystick, as input to the other.

So far i've found the love documentation to be excellent, but it really falls short on joysticks. There are nice verbose examples for most things i've looked into, but for joysticks it's rough. There is also more outdated docs then new, so i keep finding myself on irrelevant pages.

That said I should mention I'm on Love 11.4.
Any code examples of how to deal with this? I'm assuming it's because this controller isn't found in some internal index. Any help appreciated.


output from the start of my game.

Code: Select all

Registering "Mad Catz Wired Xbox 360 Controller"" as "JOY1"
Registering "PS3/USB Cordless Gamepad"" as "JOY2"
{
        ['JOY2'] = {
                ['device'] = 'Joystick: 0x558d31759d20',
                ['description'] = 'PS3/USB Cordless Gamepad'
        },
        ['JOY1'] = {
                ['device'] = 'Joystick: 0x558d31760bd0',
                ['description'] = 'Mad Catz Wired Xbox 360 Controller'
        },
        ['KEY1'] = {
                ['description'] = 'Keyboard, Using Up, Down, Left, Right keys'
        },
        ['KEY2'] = {
                ['description'] = 'Keyboard: Using W, A, S, D keys'
        }
}
Last edited by cloudfrog on Tue Mar 08, 2022 11:49 pm, edited 1 time in total.
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: Gamepad mapping

Post by ReFreezed »

love.joystick.setGamepadMapping() should be all you have to use to make an unrecognized joystick become a recognized gamepad. Is Joystick:isGamepad returning false for the troublesome joystick? Have you tried loading these mappings linked in the wiki? Can you show the code that isn't working?
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
cloudfrog
Prole
Posts: 8
Joined: Mon Feb 21, 2022 8:31 am

Re: Gamepad mapping

Post by cloudfrog »

Correction: I said I was using love 11.4 by mistake. I'm using 11.3 (Ubuntu / Mint 20.2).

Thank you for the reply and the link. This is helpful. I did not come across that link in the wiki. Mostly hopping back and forth between various methods of love.joystick. And anything I find in google points me to methods that have been removed in love 11.

The problem joystick is returning false to isGamepad, and I could not find it "by name" in the link you provided. The guid can be found as "Precision Controller".

I'll copy the code i have. I've been basically trying something, then deleting. What I will the object bound to 'JOY1' moves the way it should and 'JOY2' does nothing for all buttons and inputs; and it's the same code that i loop through for both.

Code: Select all

Registering "Mad Catz Wired Xbox 360 Controller"" as "JOY1"
Registering "PS3/USB Cordless Gamepad"" as "JOY2"
{
        ['JOY2'] = {
                ['gamePad'] = false,
                ['device'] = 'Joystick: 0x55afe35ded30',
                ['guid'] = '030000006d040000d2ca000011010000',        <------  Precision Controller
                ['description'] = 'PS3/USB Cordless Gamepad'
        },
        ['JOY1'] = {
                ['gamePad'] = true,
                ['device'] = 'Joystick: 0x55afe35f8450',
                ['guid'] = '03000000380700001647000031220000',
                ['description'] = 'Mad Catz Wired Xbox 360 Controller'
        },
        ['KEY1'] = {
                ['description'] = 'Keyboard, Using Up, Down, Left, Right keys'
        },
        ['KEY2'] = {
                ['description'] = 'Keyboard: Using W, A, S, D keys'
        }
}

Code: Select all

require("helper") --TODO delete me
Input = {}

inputSources = {}

-- KEY1 and 2 will be the same keyboard, just using different keys
inputSources['KEY1'] = { description = "Keyboard, Using Up, Down, Left, Right keys" }
inputSources['KEY2'] = { description = "Keyboard: Using W, A, S, D keys" }


-- Detect Joysticks
local joys = love.joystick.getJoysticks()
for i, js in ipairs(joys) do
     inputSources['JOY' .. tostring(i)] = { description = js:getName(), device = js, guid = js:getGUID(), gamePad = js:isGamepad() }
     print('Registering "' .. js:getName() .. '"" as "JOY' .. i .. '"')
end


print_table(inputSources) -- TODO: delete me
--love.event.quit()
Unrelated but in case you're wondering, speedAdjustment is basically just dt with some other variables factored in.

Code: Select all

function Input:update(speedAdjustment)
     Input:keyboardUpdate(speedAdjustment)
     Input:joystickUpdate(speedAdjustment)
end


function inputEvent(inputSource, what, speedAdjustment)
     if what == 'UP' then
          if     Settings.PlayerLeftInput  == inputSource then Player1:moveUp(speedAdjustment) 
          elseif Settings.PlayerRightInput == inputSource then PlayerRight:moveUp(speedAdjustment) end
     end
     if what == 'DOWN' then
          if     Settings.PlayerLeftInput  == inputSource then Player1:moveDown(speedAdjustment) 
          elseif Settings.PlayerRightInput == inputSource then PlayerRight:moveDown(speedAdjustment) end
     end
     if what == 'LEFT' then
          if     Settings.PlayerLeftInput  == inputSource then Player1:moveLeft(speedAdjustment) 
          elseif Settings.PlayerRightInput == inputSource then PlayerRight:moveLeft(speedAdjustment) end
     end
     if what == 'RIGHT' then
          if     Settings.PlayerLeftInput  == inputSource then Player1:moveRight(speedAdjustment) 
          elseif Settings.PlayerRightInput == inputSource then PlayerRight:moveRight(speedAdjustment) end
     end
end

function Input:keyboardUpdate(speedAdjustment)
     -- Inputs
     -- TODO - implement key states to avoid flickering
     if love.keyboard.isDown("q") then
          love.event.quit(0)
     elseif love.keyboard.isDown("f1") then
          Settings.debug = not Settings.debug
     end


     -- KEY id to represent match an inputSource
     local id

     -- ------- InputSource KEY1 : UDLR ----------------------------
     id = 'KEY1'
     if love.keyboard.isDown("up")  then
          inputEvent(id, "UP", speedAdjustment)
     end

     if love.keyboard.isDown("down")  then
          inputEvent(id, "DOWN", speedAdjustment)
     end

     if love.keyboard.isDown("left")  then
          inputEvent(id, "LEFT", speedAdjustment)
     end

     if love.keyboard.isDown("right")  then
          inputEvent(id, "RIGHT", speedAdjustment)
     end


     -- ------- inputSource KEY2 : WASD ----------------------------
     id = 'KEY2'
     if love.keyboard.isDown("w")  then
          inputEvent(id, "UP", speedAdjustment)
     end

     if love.keyboard.isDown("s")  then
          inputEvent(id, "DOWN", speedAdjustment)
     end

     if love.keyboard.isDown("a")  then
          inputEvent(id, "LEFT", speedAdjustment)
     end

     if love.keyboard.isDown("d")  then
          inputEvent(id, "RIGHT", speedAdjustment)
     end

end


function Input:joystickUpdate(speedAdjustment)
     --local k   -- KEY id for inputSources
-- ------- inputSource JOY1 : inputSources['JOY*''].device ----------------------------
     --k = 'JOY1'
     local id 
    -- inputtype, inputindex, hatdirection = inputSources['JOY1'].device:getGamepadMapping( 'leftx')
    -- print('MAP: ', inputtype, inputindex, hatdirection)

--     guid = inputSources['JOY1'].device:getGUID()
--     success = inputSources['JOY1'].device.setGamepadMapping( guid, 'dpup', 'button', 5, nil)
--     print(success)

     --print('LEFT_STICK_X: ' .. inputSources['JOY1'].device:getGamepadAxis('leftx'))
     --print('LEFT_STICK_Y: ' .. inputSources['JOY1'].device:getGamepadAxis('lefty'))
     for thisKey,_ in pairs(inputSources) do
          id = tostring(thisKey)
          if thisKey:sub(1,3) == 'JOY' then
               -- For this game, we don't want fine grained control from the sticks.  So we will treat them like a dpad

               if inputSources[id].device:getGamepadAxis('lefty') < -0.2 or inputSources[id].device:isGamepadDown('dpup') then
                    inputEvent(id, "UP", speedAdjustment)
               end

               if inputSources[id].device:getGamepadAxis('lefty') > 0.2 or inputSources[id].device:isGamepadDown('dpdown') then
                    inputEvent(id, "DOWN", speedAdjustment)
               end

               if inputSources[id].device:getGamepadAxis('leftx') < -0.2 or inputSources[id].device:isGamepadDown('dpleft') then
                    inputEvent(id, "LEFT", speedAdjustment)
               end

               if inputSources[id].device:getGamepadAxis('leftx') > 0.2 or inputSources[id].device:isGamepadDown('dpright') then
                    inputEvent(id, "RIGHT", speedAdjustment)
               end

          end
     end


end
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: Gamepad mapping

Post by ReFreezed »

Since the PS3 controller is in gamecontrollerdb.txt you should just have to load that file.

Code: Select all

-- Try this first.
love.joystick.loadGamepadMappings("gamecontrollerdb.txt")
print(theJoystick:isGamepad())

-- Didn't work for some reason? Try adding the mappings manually.
love.joystick.setGamepadMapping(theJoystick:getGUID(), "x"     , "button", 6, nil)
love.joystick.setGamepadMapping(theJoystick:getGUID(), "dpup"  , "hat"   , 1, "u")
love.joystick.setGamepadMapping(theJoystick:getGUID(), "rightx", "axis"  , 3, nil)
-- etc...

-- For testing:
function love.joystickpressed(joystick, button)
	print("joystickpressed", joystick:getName(), button)
end
function love.gamepadpressed(joystick, button)
	print("gamepadpressed", joystick:getName(), button)
end
(Note that the names in gamecontrollerdb.txt are completely arbitrary. Only the GUIDs matter.)
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
cloudfrog
Prole
Posts: 8
Joined: Mon Feb 21, 2022 8:31 am

Re: Gamepad mapping

Post by cloudfrog »

Thank you, loading the file fixed the problem right away. Ive been tied up with work and couldn't try 8t sooner.

This also has me wondering. Is there a way to create the mapping in game? You know, detect that something was pressed, and assign it to what the user want? Any methods i looked at where either removed or assumed that you already know what is.

It would be great to say dpleft is what ever the next input is from the joystick.
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: [SOLVED] Gamepad mapping

Post by ReFreezed »

Use the love.joystickaxis, love.joystickhat and love.joystickpressed event callbacks to detect generic input, and call love.joystick.setGamepadMapping to add the mappings. Note that there's currently no way to remove added mappings without restarting the game.

(Also, I don't know what removed methods you're talking about. The wiki only show that methods have been added to the Joystick object over time - none have been removed. Are you talking about functions in the love.joystick module?)
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
cloudfrog
Prole
Posts: 8
Joined: Mon Feb 21, 2022 8:31 am

Re: [SOLVED] Gamepad mapping

Post by cloudfrog »

Sorry I didn't see the notification.
Yes, I misunderstood how the documentation was organized.
I was looking at functions like you said here: https://love2d.org/wiki/love.joystick , which almost everything was removed in 0.9.0. I was trying a few outdated examples, so it seemed everything I tried relied on functions that no longer exist.

Thanks for pointing this out.
alejandroalzate
Citizen
Posts: 67
Joined: Sat May 08, 2021 9:45 pm

Re: [SOLVED] Gamepad mapping

Post by alejandroalzate »

one ask for nowhere WTF with joystick hat
First: before 11.3 or something like that, i've checked de dpad with joystickpressed
Second: some devices detect the dpad as four button where others detect as the POV control
WTF just WTF???

Code: Select all

target = boardIndex.getWhosPeekingThisLine()
target:setObey(true)
Post Reply

Who is online

Users browsing this forum: No registered users and 36 guests