Getting duplicated input events from two separate gamepads on Linux using evdev

78 Views Asked by At

I'm writing an input system for my engine and I'm currently trying to get controller input up and running. I have a third party X-Box controller and PS4 controller for testing. I was successful in getting input from both of them, so I then tested the system with both controllers connected at the same time. That's when I noticed some weird behavior.

If I first read events from the X-Box controller and then the PS4 controller, when I press a button on the X-Box controller, it results in two prints to the console. This is not the case with the PS4 controller.

I reversed the read order and read from the PS4 controller first. Ran the same test and this time I got two prints when pressing a button on the PS4 controller but not on the X-Box one.

After some further debugging I'm ready to believe that my controllers are mirroring each other?

I've tried searching for someone that's experienced this or a similar situation but I've not been successful. Then again I'm not too sure what to search for. From looking at the docs, I didn't see any obvious mention about a case like this, nor did I spot a way of differentiating between controllers to work around the problem.

Below is my code. I open the two files from "/dev/input/by-id" using open() and store them in state.Gamepads. Every frame I read each and process the event accordingly.

struct input_event e;
for (i32 i = 0; i < 2; ++i)
{
    if(state.Gamepads[i] <= 0) { continue; }
    read(state.Gamepads[i], &e, sizeof(e));

    if (e.type == EV_KEY && e.value == 1)
    {
        switch (e.code)
        {
            case BTN_WEST:
            LOG_INFO("BUTTON WEST PRESSED");
            break;
         }
     }

}

I expected to get individual and unique input from each gamepad. Instead I get mirrored input.

I'm very new to developing on Linux and it's been a mess to find docs and info about these APIs since I don't know where to look. Has anyone else ran into this? Is this a bug or am I doing this completely wrong?

1

There are 1 best solutions below

0
magikz On

I was able to solve my issue thanks to @dimich

The link he provided to the libevdev docs were extremely helpful with clear examples and descriptions for each function in the API.

I switched from using raw read() to libevdev_next_event() and that correctly captures individual input from both gamepads.

A full example is also provided in the docs, outlining every step.