Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

UJR - Universal Joystick Remapper (Using vJoy)


  • Please log in to reply
130 replies to this topic
evilc
  • Members
  • 340 posts
  • Last active: Oct 27 2015 11:07 PM
  • Joined: 17 Nov 2005

What is it?

A program to combine axes, buttons and the 1st hat from any of your physical joysticks into one or more 8 axis, 32 button virtual joysticks.
it should work with any game
If the joystick you wish to use appears in Windows' game controller list, it will work with UJR.
 
Why would I want it?

  • Your joystick is not recognised by the game
  • Your joystick is recognised, but an axis is the wrong way around and you cannot fix it.
  • You have a pair of racing pedals that feature an axis for each pedal, and wish to use them as a single rudder axis.
  • You want to use two devices for a game (eg a pedals and a stick/throttle) for a game but it only supports one joystick at a time.
  • You want a specific feature, but lack the knowledge to write such a thing yourself. The code is pretty easy to understand and you just need a text editor.

Features

  • "Portable" application, no installation required - just run the EXE!
  • Control up to 16 virtual joysticks with 8 Axes and 32 Buttons each!
  • Controlled by up to 16 physical joysticks
  • Invert any axis
  • Per-axis deadzone and sensitivity settings
  • Axis Merging - Combine two racing pedals into a rudder!
  • Axis Splitting
  • Remap the 1st Hat (POV) switch to any buttons.
  • Settings saved between uses
  • Profile support
  • Run multiple copies - each copy can control a different virtual stick
    (But each version can read any of the physical axes)
  • "QuickBind" mode to control the virtual joystick via the UJR GUI 
    Use this when the game detects the underlying physical stick instead of the virtual one - allows you to move the virtual stick without moving the physical stick

How does it work?

  • Uses the free open source app vJoy to create a virtual joystick
  • UJR is written in AutoHotkey, an open source macro app - it sends instructions to vJoy via Axlar's vJoy to AHK Bridge.
  • Configure UJR to tell it which physical joystick axis/button controls which axis/button of the virtual joystick - each axis and button of the virtual stick can be mapped to a different physical joystick

Can I modify and freely distribute it?
Yes, if you add a cool new feature, or know a better way of writing a bit of the code, please let me know!
 
Cool! Where can I get it?
 
Direct Download: 
http://evilc.com/fil...hk/vjoy/ujr.zip
 
Homepage:
http://evilc.com/proj/ujr
 
GitHub Page:
https://github.com/e...ystick-Remapper
 
We now have a signed driver, so Windows 7 x64 users no longer need to use Test Mode!
 
Full instructions are in the readme inside the zip
 
ujr.png



evilc
  • Members
  • 340 posts
  • Last active: Oct 27 2015 11:07 PM
  • Joined: 17 Nov 2005

Changelog


Key:
! : Warning
* : Comment
= : Change / Fix
+ : Added feature
 

6.3 12th Dec 2013
= Fixed missing 9-16 option for dropdowns to select stick ID for buttons, hats etc.
 
6.2 12th Dec 2013
+ UJR now supports 16 physical joysticks (The max windows supports), instead of 8.
 
6.1 10th Dec 2013
= Fixed bug with axis merging.
  Axis was being flipped in "Rests H" mode, also deadzone was applying wrong.
  Sorry! I have no idea what I was smoking when I wrote that code!
 
6.0 7th Dec 2013
! Profiles from previous versions of UJR are not compatible with this version
  Please delete or re-name uhr.ini
! VJoy library was updated - be sure to copy the contents of VJoyLib folder over old copy!
= Changed Axis Merging mechanism
  Should be simpler to understand now
+ Axes and Buttons unavailable on the virtual stick are now disabled in UJR.
  If your virtual stick only has 16 buttons, buttons 17-32 will be disabled in UJR.
+ Real-time detection of available axes / buttons.
  If you alter the virtual stick config with UJR running, it will detect the changes and update accordingly.
+ Can now control different virtual sticks and swap virtual stick on the fly.
+ Can now run multiple copies of UJR simultaneously.
  Each copy of UJR can control a different virtual stick.
+ Axis Splitting
  Can now use half a physical axis to control a virtual axis
+ Improved Deadzone / Sensitivity support
  Per-axis dz / sens support when doing axis merging
  Rest High / Low mode for applying dz / sens to one end of an axis (For throttle / pedal like axes)
= Fixed bug with Copying profiles (Exiting and reloading would not result in copied profile being the current one)
 
5.4 30th Nov 2013
= Modification to VJoy library - it can now correctly control virtual stick IDs other than 1.
  No actual changes to UJR, but it would now be easy to make UJR control any virtual stick ID (Currently thru a code edit).
  BE SURE TO COPY THE VJOYLIB FOLDER FROM THE ZIP INTO YOUR UJR FOLDER - THAT IS WHERE THE MAIN CHANGE IS!
 
5.3 25th Nov 2013
= Reduced likelihood of a merged axis "kicking" in one direction.
  Previously, when building the virtual axis, the value of the first axis would be applied,
  then the value of the second axis would be averaged in and the virtual axis would be set again.
  This could result in jerky movement if there was too long between the two physical axes being processed.
  The virtual axis is now only set when both physical axes have been read and added together.
 
5.2 25th Nov 2013
! Axis merging has changed!
  It is now much less confusing to set up - configure each axis individually to move the slider in the direction desired.
  eg set the left pedal to move the slider left (from a resting position all the way right), right pedal to move it right.
  Then set both axes to the same virtual axis and enable merge - it should behave as expected.
+ Now detects if something else is controlling the virtual stick (maybe you tried to run ahk and exe versions of UJR?) and exits.
 
5.1 21st Nov 2013
+ Added "QuickBind" function - bind game functions without leaving the game!
  Instead of manually selecting an axis or button by using the QB radio button, you can use QuickSelect.
  Bind QuickSelect to something, and when you hit it, press a button or move an axis.
  The relevant axis or button will then be selected for you.
+ "Auto Configure" function - quickly set up a straight through mapping for all buttons or axes.
 
5.0 20th Nov 2013
* Rewrite using my ADHD library.
! Now intended to be used when compiled to an EXE - You no longer need AutoHotkey installed.
! Old profile files are NOT COMPATIBLE.
  However, it is just the groups etc in the INI that will not work right.
  If you create a new profile, exit UJR and paste in the contents of the old profile, it may well work.
= Manual Control is gone, replaced by QuickBind
= Profile support improved
= Less tabs
= Improved hat switch support (QuickBind supports hats, whereas Manual Control did not)
= Detect Axis gone for now, it will probably return
 
4.3
+ Basic support for Hat (POV) switches in.
Only "Continuous" hats supported for now.
Hats have no "Manual Control" mode for now
 
4.2
= Duplicate in profiles was always duplicating the Default profile, no matter what you had selected - fixed.
+ Added Delete Profile button
 
4.1
+ Duplicate profile added.
 
4.0
+ Profile support added.
INI file format changed, there are now two INI files - one for misc settings, one for profiles
Existing mappings are kept and moved to the default profile
Manual profile switching only for now...
 

3.2

+ The first physical POV Hat can now be mapped to virtual buttons. AHK only supports reading one POV sad.png
 
3.1
+ Sensitivity option for each axis.
 
3.0
! Please note that the format of the config file has changed, the program will back your old one up
= Fixed bug stopping button mappings not saving
= Improved UI layout, labels etc
= Major cleanup of code - now much more understandable
+ GUI position now saved in config file - when you close the app, next time you reopen it, it will be in the same place on your desktop
+ Only settings changed from their default setting are stored in the config file
+ Detect axis button! Use this to try and find out the stick ID of a physical stick.
Instructions now simplified
+ Experimental - Merging of axes
eg Merge two pedal axes into a rudder axis


2.3
+ Much improved deadzone code
So with a 50% deadzone, if you move to 50 on an axis, it will be dead, but moving to 51 now outputs 1 rather than 51
+ Deadzone is now a text input field, so you can use any value you like
+ Input / Output slider renamed to "State"
+ Input and Output values for axes now displayed
+ Much more commented code

2.2
+ Added per-axis deadzone settings. Just 5,10,20,30,40,50,60,70 or 80 percent at the moment but I intend to allow any figure in a future version


2.1
= Fixed bug stopping UJR from working on 64-bit AHK installs.
= Fixed bug stopping mapping of virtual axis 4 or greater
+ 32 Buttons listed for physical joystick

2.0
+ Now uses Axlar's vJoy library (http://www.autohotke...to-control-vjoy)
+ Now uses vJoy 2.x - Support for up to 32 buttons
You will NEED to uninstall vJoy 1.x and install 2.x to use this version

1.1
= Code for button testing no longer has one subroutine per button
= Optimised technique for inverting axes - thanks Babba on AHK forums!

1.0
* Fully functional basic version!
= Fixed bug stopping invert working in Manual Control mode
+ Button mapping in

0.3
+ Settings now saved in an INI file

0.2
+ All 8 axes now mappable
+ Code optimisations

0.1
- Initial Proof of concept



axlar
  • Members
  • 196 posts
  • Last active: Dec 04 2015 08:50 AM
  • Joined: 29 Nov 2012

Hi evilc,

 

 

 

So... a couple of issues I would like to solve

 

I would like to be able to refer to GUI controls by an array, eg like:
Gui, Add, DropDownList, x132 y40 w60 h21 R7 vAxis[1] gConfigChanged, 1|2|3|4|5|6
Gui, Add, DropDownList, x132 y70 w60 h21 R7 vAxis[2] gConfigChanged, 1|2|3|4|5|6
(Note the vAxis[1] ,vAxis[2])

 


Error "The following variable name contains an illegel character" was displayed when I used associated variable with "[number]".

I think "[]" cannot be used for variable that associated from control... (checked "Storing and Responding to User Input" but no notices found)

In my traditional approath:

    AxisMapping := Array()
    Loop, 8
    {
        xpos = % "x" . (A_Index-1)*62
        Gui, Add, DropDownList, %xpos% y40 w60 h21 R7 vAxis_ID_%A_Index% gConfigChanged, 1|2|3|4|5|6
        Gui, Add, DropDownList, %xpos% y70 w60 h21 R7 vAxis_Axis_%A_Index% gConfigChanged, 1|2|3|4|5|6
    }
    Gui, Show
return

ConfigChanged:
    Gui, Submit, NoHide
    Loop, 8
    {
        AxisMapping[A_Index,1] := Axis_ID_%A_Index%
        AxisMapping[A_Index,2] := Axis_Axis_%A_Index%
    }
    MsgBox, % AxisMapping[8,1] . "," . AxisMapping[8,2]
return


evilc
  • Members
  • 340 posts
  • Last active: Oct 27 2015 11:07 PM
  • Joined: 17 Nov 2005

Nice solution, thanks!



evilc
  • Members
  • 340 posts
  • Last active: Oct 27 2015 11:07 PM
  • Joined: 17 Nov 2005

OK, next question:

 

With axes in AHK and the PPJoy library being 0-100, what is the most efficient way to, say, invert this axis?

 

If axes were in the format -1 to 1, this is simple, you just multiply by a variable which holds either 1 or -1

 

Is there an easy (as in fewest CPU cycles) to do this with a 0 to 100 scale?

 

At the moment, I use the algorithm (value - 50) / 50 to convert to a -1 to 1 scale, then do the invert, then convert it back using (value * 50) + 50



evilc
  • Members
  • 340 posts
  • Last active: Oct 27 2015 11:07 PM
  • Joined: 17 Nov 2005

New version up - 0.2 (Same link)

 

Now all 8 axes are mapped.

 

Thanks axlar for the neat solution!



strobo
  • Members
  • 359 posts
  • Last active: Mar 10 2015 08:13 PM
  • Joined: 19 Jun 2012
Is there an easy (as in fewest CPU cycles) to do this with a 0 to 100 scale?

100-value

but this makes hardly any cpu load difference in your application.


Regards,
Babba

evilc
  • Members
  • 340 posts
  • Last active: Oct 27 2015 11:07 PM
  • Joined: 17 Nov 2005
100-value

You maybe misunderstand.

If you have the option to invert axes, with a -1 to 1 range, you can store 1 for "not inverted" or -1 for "inverted" in a variable "invert"

 

then do like: output = axis * invert

 

with a 0 to 100 range, I cannot work out a similar algorithm.

 

 

So I need something like:

 

output = axis + (100 * invert)

 

where I can have two possible values in invert - one that inverts the axis, one that leaves it alone.

 

Sure it can be done with conditionals, but I feel there has to be an algorithm or built in function to do this.



strobo
  • Members
  • 359 posts
  • Last active: Mar 10 2015 08:13 PM
  • Joined: 19 Jun 2012

Uhm, you maybe don't know the ternary operator? Until then you might use

50+(value-50)*invert


Regards,
Babba

evilc
  • Members
  • 340 posts
  • Last active: Oct 27 2015 11:07 PM
  • Joined: 17 Nov 2005

Uhm, you maybe don't know the ternary operator? Until then you might use

 

50+(value-50)*invert

A ternary operator is still a conditional. I was hoping to solve this with one equation.

 

50+(value-50) does nothing - you are adding 50 and taking away 50.



evilc
  • Members
  • 340 posts
  • Last active: Oct 27 2015 11:07 PM
  • Joined: 17 Nov 2005

New version up - 1.0

Fully functional (Though basic)



evilc
  • Members
  • 340 posts
  • Last active: Oct 27 2015 11:07 PM
  • Joined: 17 Nov 2005

Hmm, hang on, apologies.

Not 100% sure on my BODMAS, but you are correct on the maths - I would have written it thus for clarity:

 

50+((value-50)*invert)

 

Thank you!



evilc
  • Members
  • 340 posts
  • Last active: Oct 27 2015 11:07 PM
  • Joined: 17 Nov 2005

New version up, 1.1

 

No functionality changes, just some optimisations.

 

Used Babba's suggestion for the formula, plus I managed to make the code more elegant - no more one subroutine per button.

So I should be ready to swap over to axlar's library with it's support for 32 buttons pretty much by setting a variable to 32.

Am slightly concerned about space in the GUI though. Rather than make it larger, I was thinking of having 4 tabs for the buttons: 1-8. 9-16 etc. 



evilc
  • Members
  • 340 posts
  • Last active: Oct 27 2015 11:07 PM
  • Joined: 17 Nov 2005

Lots more versions since I last updated here - deadzone support, 32 buttons, etc etc



evilc
  • Members
  • 340 posts
  • Last active: Oct 27 2015 11:07 PM
  • Joined: 17 Nov 2005
Another load of changes - now up to v3.0

See changelog in original post.