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?
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()tolibevdev_next_event()and that correctly captures individual input from both gamepads.A full example is also provided in the docs, outlining every step.