WhiteMagic / JoystickGremlin

A tool for configuring and managing joystick devices.
http://whitemagic.github.io/JoystickGremlin/
GNU General Public License v3.0
313 stars 45 forks source link

"Merge axis" for more than two devices? #462

Closed Pomax closed 1 year ago

Pomax commented 1 year ago

I have a flight stick, a yoke, and a little trim controller, and as I don't use the yoke and flight stick at the same time, it would be super useful if one could merge three (or more? I need three though) rather than two devices into the vJoy device, so that I can simply sum the stick, yoke, and trim controller, and not need to leave my game to juggle different configs depending on which flight controller is more appropriate to the model I just loaded up.

WhiteMagic commented 1 year ago

This is not something the UI supports or ever will, but the user plugin system is intended for such more obscure functionalities. One plugin that might already do what you need is this https://gist.github.com/WhiteMagic/63b8cd650f91035e2caeb9dc226d0c3f and if not it should be a good starting point.

Pomax commented 1 year ago

Ah, bit of a shame on the UI side (being able to add devices between the existing ones and the output with a little [+] button would have been super nice) but thanks for that plugin script link!

It might be cool to include that gist (and other?) as scripts in a custom_plugins/demos dir or something in the release?

TheGoodIdeaFairy commented 1 year ago

@Pomax There is a workaround that I've been using to implement complex axis input profiles, but it does require a higher than usual number of vJoy devices. For most (possibly for all) "joystick" type actions or conditions (ie. those requiring a GUID in the XML), a vJoy GUID may be provided in lieu of a physical device GUID. This means you can treat vJoy type action-conditions as joystick type, sidestepping the vJoy condition reset bug. This also means you can implement vJoy axis merges.

These techniques must be done via the XML directly (I HIGHLY recommend you maintain version control via new saves or git). If you're uncomfortable editing XML or need advice lmk and I can advise further... trying to avoid a 3ft wall of text here.

The technique for combined merges is as follows: 1) Add the required number of vJoy devices (determined by how many axes you will be creating)... WARNING: creating new vJoy devices shuffles the GUIDs of existing vJoys, so any existing GUID based vJoy settings will have to be updated. I suggest you add as many vJoy devices as you anticipate ever needing before you start making these types of alterations. If you've only made settings via JG's UI until now, this GUID shuffling issue should not affect you. 2) Hide the HIDs of all vJoy devices that aren't intended to be used directly for output using HidGuardian/HidHide/etc. Example: I have the first 5 vJoy devices reserved as input devices, whereas the remaining 11 devices are hidden, reserved for current or future use as meta/logic devices. 3) Within JG, create the number of axis merges you will need (how to determine this count explained below). 4) Within JG, name each vJoy device in the "Device Label" field according to its number on the tab. This will assist in identifying the correct GUIDs in the XML. Save to new file. 5) Open this file in XML editor of your choice (notepad++ with XML plugin turned on is sufficient). Toward the bottom is the section for "Merge-Axis" entries. 6) According to your pre-planned merges (see below), replace the value of "device-guid". Do the same for "axis-id" if you didn't already set these through JG. vJoy GUIDs are pulled from the "vjoy-devices" section of the XML. 7) Save this file (again, I recommend a new save) and load into JG. WARNING: if at any point you open the Merge-Tool in JG and subsequently save, all vJoy device GUIDs will be overwritten by physical device GUIDs. After you've completed the setup for your combined merges, I suggest you save/backup an extra copy of your XML profile so that if this were to happen you can simply copy/paste the vJoy merges over the overwritten ones.

Planning Your Merges: For your use case, your merge plan would look like this: image This layering can be repeated essentially ad-infinitum. Essentially each layer after the first adds an additional input axis to the mix. Any input axis can be either a physical axis or a vJoy axis.

If a vJoy axis is used you can control its set point via macros. This might look something like this: image *This is out of scope for your use case, but you might find this useful anyway.

Note 1: I recommend also changing the device name (where present, IIRC only on action conditions) to a consistent label such as "vJoy-01/02/etc" for sanity. Note 2: Make sure that vJoyConfig, JoystickGremlin, and all associated utility programs are added to the exception list for HidHide or other HID cloaking utility.

Of course, none of this is supported in the UI, and @WhiteMagic might be mad at me for abusing his software (;D), but it works quite well and opens up a world of customizability.

TheGoodIdeaFairy commented 1 year ago

@Pomax PS: There's an additional extension to this method that I've used in order to apply individual response curves to the physical axes prior to merging (rather than only applying a response curve to the resulting merge, which is a limitation of the above structures): image

A bit more complex, but essentially follows the same logic.

Pomax commented 1 year ago

While I'm sure that works, that's also way more work than the relatively simple script from the above-mentioned gist, also incurring a higher CPU cost in order to deal with five, rather than one, vjoy devices =)

TheGoodIdeaFairy commented 1 year ago

All good. More flexible, but yes... definitely more complex. As far as CPU cost, it's negligible. The weight of JG barely registers as 1% CPU usage at peak, and that's with a frankly absurd number of loops running, haha. I'm glad you found a solution that worked for your use case, hopefully someone else comes across this and is helped along by it.