jgeumlek / MoltenGamepad

Flexible Linux input device translator, geared for gamepads
MIT License
280 stars 42 forks source link

Multiple virtual keyboard/mouse #65

Open gustavoalara opened 5 years ago

gustavoalara commented 5 years ago

Hi,

I'm using moltengamepad for an Arcade Cabinet project where I use a wiimote as LightGun configuring moltengamepad as mouse. The problem is if I connect two wiimotes with moltengamepad I have two virtual gamepads (what is perfect) however I only have one mouse/keyboard and the two wiimotes move the same cursor pointer.

Currently for two players LightGun games I'm using one wiimote as mouse with molten and the other with DolphinBar. This configuration is not bad, but I prefer molten because when I use molten as IR mouse I can use the same wiimote as virtual gamepad and mouse, but DolphinBar only see wiimote as keyboard+mouse.

I tried use the gyroscope option, but with gyroscope I only can use the wiimote as mouse+keyboard and not as gamepad like using IR mouse option.

is it possible to create multiple virtual keyboards/mouse as in the case of gamepads?

Thanks a lot, in the meantime, I'm going to investigate the code and see if I can do it.

jgeumlek commented 5 years ago

Back in a previous project, WiimoteGlue, I messed around with multiple distinct virtual mice, but eventually abandoned it since even with X11's multiple cursor support, it was hardly useful.

However, that is indeed a compelling use case! I should have foreseen such arcade purposes.

Short answer: there is nothing technical stopping MG from having multiple mice, but it would take some work on the code. The current state of the software does not support it.

Long answer: Most of the work would need to be done in source/core/slot_manager.cpp. This class holds all the virtual output devices, and manages assigning our input sources to them. It has a dynamic list of virtual gamepads, plus one keyboard slot.

A quick-and-dirty implementation would not take a ton of work, where the number of keyboard/mice devices is hardcoded. Just make a list of keyboard slots too, initialize them in the same way, and then you could manually "assign" devices to each keyboard. Not trivial, but not crazy either.

A more involved implementation would duplicate the logic for gamepad slots: when an input source requests a slot assignment, we need to scan the list of slots for availabilities, so that we don't end up dumping them all onto the first keyboard.

And a yet more involved implementation would define sensible configuration options for this behavior, and expose that option the same we let the number of gamepads be configured.

gustavoalara commented 5 years ago

Thanks a lot!

I figured that it could be possible. I'll take a look at the code in source/core/slot_manager.cpp and try to understand the logic of it and do what you tell me (although I have my C++ a little rusty)

gustavoalara commented 5 years ago

Hi jgeumlek

I managed to create a second keyboard slot, however when I assign the second wiimote to the second keyboard (through move wm2 to keyboard_2) it doesn't work and both wiimotes continue moving the mouse of the keyboard_1 Could you give me a hint of what function to modify to assign the second wiimote to the second keyboard?

Thanks so much

gustavoalara commented 5 years ago

In my second attempt I have achieved that the first wiimote works as Gamepad1+mouse1 and the second wiimote I can move it to the slot of the second keyboard... But it runs out of Gamepad and the mouse doesn't work

The evtest shows me correctly that there are 2 virtual Gamepads, two keyboards and two mice, however I am unable to make the second wiimote behave like the first,

So that the first one works as Gamepad and mouse without moving it to the keyboard slot1 I have the configuration like this:

Wiimote.wm_ir_x = mouse(abs_x) Wiimote.wm_ir_y = mouse(abs_y)

Thanks

jgeumlek commented 5 years ago

If I follow correctly, you have your second keyboard-n-mouse working. If you move the wiimote to it, sends virtual events to the correct secondary keyboard and mouse.

The issue is that if you move it to the second keyboard, you move it off of the second gamepad, and you still want to be able to send gamepad events. Having it on just one slot or the other isn't quite enough.

That does make things a bit more complicated.


Quickest and dirtiest: In the second wiimote, set the profile to ... = redirect(abs_x, <kb2slotname>). The mouse(...) event translator is pretty much just an alias for redirect(..., keyboard).

(similarly, you should be able to redirect events back onto the second gamepad if you wanted to instead)


Slightly nicer: in addition to the mouse(...) redirect, you can put in a mouse2(...) redirect that similarly redirects to the second keyboard slot. You can see how I build this fake alias in parser.cpp, trans_gens["mouse"] = ..., but the code is a bit hairy since it deals with the generic framework I built for parsing event translators with various options.

Then the second wiimote can be ... = mouse2(...).

If you want to get extra fancy, it would be possible to add an optional argument to the existing mouse translator.


However, neither of those quite achieves what I think is ideal, where the two wiimotes can share the same profile, and we can fully use the auto slot assignment functions to figure out which wiimote gets what devices.

For that to work, we would pretty much need to add some notion of mapping virtual gamepads to having associated virtual keyboards, whether that is by holding references to other keyboard slots, or by changing the virtual device creation of the gamepad slots to also create some mice.

Not impossible, but it would take some reworking. This would also require disambiguating ABS_X and ABS_Y events, since both a gamepad and a virtual keyboard-mouse may want to consume those events, and once the gamepads can handle figuring out where their keyboard events go, the existing key(...) and mouse(...) redirects would need to be changed too.

gustavoalara commented 5 years ago

Hi jgeumlek,

The quickest and dirtiest approach has worked. Maybe is not the fanciest solution, but works for now. I've tested with pixel desktop in a raspberry pi 3B+ with Retropie and works like a charm and I can see two mouse pointers that I can move with their assigned Wiimote.

In summary,

I've hardcoded the second keyboard in a few files appart of slot_manager.* I've compiled the new moltengamepad executable The Wiimote profile contains the following lines: _Wiimote.wm_ir_x = mouse(abs_x) Wiimote.wm_ir_y = mouse(absy) Then I can run moltengamepad and insert the following commands _Wm2.wm_ir_x = redirect(abs_x, keyboard2) Wm2.wm_ir_y = redirect(absy ,keyboard2) With this configuration I have two wiimotes that act as gamepad and mouse individually. I checked it in pixel desktop and using the evtest command

My next step is check this solution with Retroarch (but I have no doubts that will work)

If you don't care, I will open a new request to improve moltengamepad with the changes you proposed. With this workaround I am not in a hurry, but I think it would be a good improvement and very useful for arcades, I would even propose that you could do the same with the gyromouse ... Although I think this is already asking too much. I hope you will support the idea and encourage you to develop it.

Thank you very much for this great software, for your support and understanding and for the help you have offered me.

MisterXYZ83 commented 1 year ago

@gustavoalara Hello! i've managed a similar problem with arcade system and multiple lightguns. I think i have solved the problem with creation of two supplementary keyboards in slot_manager.cpp. Then my configuration is formally little different from yours i think but it should be the same conteptually:

wm1.wm_ir_x = redirect(left_x,keyboard1) wm1.wm_ir_y = redirect(left_y,keyboard1) wm2.wm_ir_x = redirect(left_x,keyboard2) wm2.wm_ir_y = redirect(left_y,keyboard2)

This way it works but after a few minutes during play my system crashes like a reboot. Have you experienced any system crash like me? It works with only one wiimote.

I tried lr-flycast retroarch core, if you can try. I tried two lightgun games, same result.

thanks :)