Please do not post a support request without first reading and following the advice in https://retropie.org.uk/forum/topic/3/read-this-first

input_pipe another joystick mapper



  • Hi, I am not sure if a pi is fast enough for this one, because I programmed it for my personal needs and it is run in an x86_64 environment and it is written in Python.
    In fact it is the first Python program I have ever written.
    But nevertheless I am dropping the link here, because I got it working today and with very satisfying results.

    What is this? Basically a universal joystick mapper which can map m:n situations. Aka m physical input devices which can send events, then translate those events into something else defined by a configuration and send those to n virtual output devices.

    I needed something like this because I have been working on a rather complex custom arcade panel, and none of the existing linux solutions really worked out for me, I always hit a wall for various reasons.

    Either way, here is the link to the repo, you might wanna check it out.
    Extensive configuration files can be found in the resources dirs in the source code and the configuration is explained in the readme.

    https://github.com/werpu/input_pipe

    also here is a video i did a few days ago for a friend of mine:

    and in action

    those were rough builds, it now can act standalone outside of the ide as daemon process.
    In fact I have hooked it now into my system via systemd and hot plugging handling is done by the mapper itself watching the udevs, so no need for any udev rules.


  • Global Moderator

    That looks quite interesting - a neat project.



  • @mitu Thanks a lot, just in case you guys are interested for which hardware I am developing this for:

    https://imgur.com/a/WAv7XZl


  • Global Moderator

    How did you get to develop such input multiplexer and how are you using it right now ?



  • @mitu well check the screenshots of my hardware and the video.
    I simply hit a wall with the existing solutions I found. The closest I found which was semi working was Moltengamepad, but the project is basically abandoned and I ran into myriads of bugs. Fixing those was too timeconsuming.

    Moltengamepad wanted simply too much for its own good, it even had its own config file parser and command line add on top of that C.

    So I stripped out the good ideas of MG and trimmed them down to what I needed and programmed this multiplexer/m:n pipe in about 3 weeks of sparetime work. (after giving myself a 10 minutes python crashcourse)

    I am not using it yet, I have been testing it so far via various emulators which hook themselves into the virtual xbox pads. They work well, the input lag is not worse than with the C written MG at least on an X86 system using a Ryzen 2400g. Also Emustation already works. Those programs just see the gamepads and keyboard and mouse inputs on the lowest level possible. So why shouldnt they work?

    In fact I just finished today the first version, I do not even have a tag yet, and about an hour before writing this post I hooked it into my system via systemd.

    Just to explain my usecase:
    I have two digital sticks two analogs, then 18 main buttons 4 top buttons 4 sidebuttons and about 11 front buttons and they should map into

    2 analogs 1 digital and 12 top buttons into xbox pad 1
    1 analog and 11 buttons into a semi working xbox pad 2
    trackball and spinners into mouse movements (done automatically)
    2 left pinball buttons into mouse left and mouse right
    front row and right siderow whatever comes along (currently keyboard keys, but I just got the idea of making a macro output device which can trigger shell scripts)

    To become even more technical, I achieved a rather fast speed despite slow Python by choosing the data structures wisely (I tried to avoid high runtime complexities wherever possible, the event matching runs in an O(log n) due to the tree structure of the rules tree and on the other side, I avoided polling and used reactive apis wherever possible, the entire event handling/triggering is done via the asyncio apis and those hook into native bindings (they existed I jused used this stuff)



  • @werpu that joystick build is absolutely amazing! Well done.



  • @simpleethat Hi just to add some additional info.
    I did some time measurement from the moment the multiplexer receives the event to the time it has finished sending the transformed data to the virtual output device. Aka one event in the event loop.

    I came around 5-8 microseconds on plain python (pypy is not usable with the evdev library)

    So I was around 7e-5 seconds with is about 0.07 miliseconds, the input lag this program introduces therefore is neglectable. It might be slower on a raspberry pi however, I have been testing this on a ryzen 2400g system.



  • @simpleethat said in input_pipe another joystick mapper:

    @werpu that joystick build is absolutely amazing! Well done.

    Thanks for the flowers, it was a lot of work... and frankly spoken a money sink as well.



  • I just added an exec functionality to my multiplexer:
    The idea is, to allow external programs to be executed on a button press. This can be used to enable/disable special functions which are triggered by external executables:

    Here is a demo and you get an idea why I need this functionality:



Contributions to the project are always appreciated, so if you would like to support us with a donation you can do so here.

Hosting provided by Mythic-Beasts. See the Hosting Information page for more information.