Linux Joystick Mapper Wiki
Status: Beta
Brought to you by:
alexandrehardy
A linux userspace device driver that allows joystick events to be remapped. Several joysticks can be combined into a single controller, and button/axes events can be remapped to new joystick, keyboard or mouse events. Advanced scripting also supported.
For a graphical UI to program the joystick (using this software) please see https://rensg.home.xs4all.nl/rb3d/joymixerUI.html
@mpd -- I believe the mouse cursor jets to the bottom of the screen because you do not have min/max/deadzone/flags defined. Try adding those to your first set of axis mappings. The good news is that C&C is finding the mouse, it's just not been configured correctly.
For example, here's an excerpt of my joymap axis configuration for a 8Bitdo SNES controller. Keep in mind your min/max/deadzone values will likely be different. Use a combination of jstest and trial & error to find the correct values.
Also, you'll want to disable the joystick in DOSBox since it looks like you're using joymap to emulate a keyboard/mouse setup.
For your DOSBox configuration:
ok ... making progress slowly ... I set the min and max to 0 and 255 respectively and now I can sort of move the cursor around ... but it is super sensative and always returns to the upper right corner now.
How do i determine the best min and max and deadzone ?
Thanks
Last edit: mpd 2017-03-14
setting the sensitivity to 2 in the dosbox config seems to have slowed the mouse down ... but that setting seems really low ... is it tied to min and max ? also the mouse is drifitng to the top right corner in the rest statre.
also ... within the actual game (the mouse cursor of the game ... the mouse is even faster.
Last edit: mpd 2017-03-15
Almost working ... had to reduce range from 32767 to 255 and now I only have a slight drift to the right and up ... now I am trying to get mouse buttons mapped to the joystick buttons ... no luck so far.
jstest is reporting Button 0 and 1 fo the buttons I want to use for the mouse buttons. The device names for these buttons is BtnY and BtnZ ... is there a way to use these names ?
I also set my sensitivity in my dsobox config to 20.
Last edit: mpd 2017-03-15
this would be an awesome tool if it were easier to configure.
Good evening, so far I was able to make my Saitek X-56 pro working, unti I put more than 32 buttons, then it fail to register axis and buttons, like if it just freeze up, but as soon as I drop the amount of buttons below 32, it works again. My joystick have 15 axis and 50 buttons, how to make it work? I've look into the source code and I saw that max_buttons was set at 32, and I tried to raise it to 64, but it made no difference. (after a make clean and a new make of course).
Any ideas?
Hello! Is it possible to bind two different controllers with the same vendor and product IDs? loadmap seems to select the joystick with the highest id (e.g, it selects
js1
when I also have ajs0
). I suppose this would be possible using theid
key, although I can't find much documentation on how this works exactly.The docs only seem to specify how the id can be found in
/proc/bus/input/devices
. I've tried making bindings where id=0, id=1 and counting, where my controllers never respond. This is the output of my two controllers in/proc/bus/input/devices
:loadmap also finds both devices and lists them as having the same vendor and product id:
Alas, it will only select the last controller detected. Is there any way around this?
Last edit: P C 2017-07-10
Dear Alexandre,
first thanks for the cool driver, which works great mostly. Still I struggle with my joystick controller.
I would really appreciate if you could advise.
The joystick features only one arcade stick, physically. But I can toggle beetween two modes with a h/w push button. First mode maps axis 0/1 to the stick, next mode maps 5/6 to the stick. If I use the mapping GUI from DOSBox axis 5/6 reports as a "HAT". My intention is to use 0/1 for mouse emulation and axis 5/6 for keyboard emulation. So far I can use all buttons and the mouse. But the keyboard part gives me headaches.
I use joymap-0.4.2.
If the map looks like: I cant trigger any axis 5/6 character, while mouse and buttons are fine:
axis vendor=0x0079 product=0x0006 src=0 target=mouse axis=0 min=0 max=255 deadzone=127 speed=6
axis vendor=0x0079 product=0x0006 src=1 target=mouse axis=1 min=0 max=255 deadzone=127 speed=6
axis vendor=0x0079 product=0x0006 src=5 target=kbd plus="r" minus="l" min=-1 max=1 deadzone=0 flags=trinary
axis vendor=0x0079 product=0x0006 src=6 target=kbd plus="d" minus="u" min=-1 max=1 deadzone=0 flags=trinary
button vendor=0x0079 product=0x0006 src=6 target=mouse button=0
button vendor=0x0079 product=0x0006 src=7 target=mouse button=1
button vendor=0x0079 product=0x0006 src=1 target=kbd button="s"
button vendor=0x0079 product=0x0006 src=2 target=kbd button="esc"
button vendor=0x0079 product=0x0006 src=3 target=kbd button="space"
If I change it to the following, it loops the r button
axis vendor=0x0079 product=0x0006 src=5 target=kbd plus="r" minus="l" min=0 max=255 deadzone=127 flags=trinary
axis vendor=0x0079 product=0x0006 src=6 target=kbd plus="d" minus="u" min=0 max=255 deadzone=127 flags=trinary
This change gives me no feedback on axis 5/6:
axis vendor=0x0079 product=0x0006 src=5 target=kbd plus="r" minus="l" min=-32767 max=32767 deadzone=2000 flags=trinary
axis vendor=0x0079 product=0x0006 src=6 target=kbd plus="d" minus="u" min=-32767 max=32767 deadzone=2000 flags=trinary
Axis 0/1 (mouse) and all buttons are active with all maps above.
jstest /dev/input/js0/
here I triggered axes 0:-32767 (all others were untouched) in the first h/w mode
Axes: 0:-32767 1: 0 2: 0 3: 0 4: 0 5: 0 6:-32767 Buttons: 0:off Axes: 0:-32767 1: 0 2:-32767 3: 0 4: 0 5: 0 6:-32767 Buttons: 0:off Axes: 0:-32767 1: 0 2: 0 3: 0 4: 0 5: 0 6:-32767 Buttons: 0:off Axes: 0:-32767 1: 0 2:-32767 3: 0 4: 0 5: 0 6:-32767 Buttons: 0:off 1:off 2:off 3:off 4:off 5:off 6:off 7:off 8:off 9:off 10:off 11:off
here I triggered axes 6:-32767 (all others were untouched) in the second h/w mode
Axes: 0: 255 1: 255 2: 0 3: 32767 4: 32767 5: 0 6:-32767 Buttons: 0:off Axes: 0: 255 1: 255 2:-32767 3: 32767 4: 32767 5: 0 6:-32767 Buttons: 0:off Axes: 0: 255 1: 255 2: 0 3: 32767 4: 32767 5: 0 6:-32767 Buttons: 0:off 1:off 2:off 3:off 4:off 5:off 6:off 7:off 8:off 9:off 10:off 11:off
jscal -c /dev/input/js0 gave me the following output. Axis 0+1 (-32767/32767) & 5+6 (-1/+1) were responsive. None of the others. I used the h/w button to change between the modes to map axis 0/1 and 5/6 as the calib requested the input.
Axis 0: 127, 127 Axis 1: 127, 127 Axis 2: 126, 136 Axis 3: 127, 127 Axis Axis 0: 127, 127 Axis 1: 127, 127 Axis 2: 126, 136 Axis 3: 127, 127 Axis Axis 0: 127, 127 Axis 1: 127, 127 Axis 2: 126, 136 Axis 3: 127, 127 Axis Axis 0: 127, 127 Axis 1: 127, 127 Axis 2: 126, 136 Axis 3: 127, 127 Axis Done. Precision is:
Axis: 0: 0
Axis: 1: 0
Axis: 2: 10
Axis: 3: 0
Axis: 4: 0
Axis: 5: 0
Axis: 6: 0
Move axis 0 to minimum position and push any button.
Hold ... OK.
Move axis 0 to center position and push any button.
Hold ... OK.
Move axis 0 to maximum position and push any button.
Hold ... OK.
Move axis 1 to minimum position and push any button.
Hold ... OK.
Move axis 1 to center position and push any button.
Hold ... OK.
Move axis 1 to maximum position and push any button.
Hold ... OK.
Move axis 2 to minimum position and push any button.
Hold ... OK.
Move axis 2 to center position and push any button.
Hold ... OK.
Move axis 2 to maximum position and push any button.
Hold ... OK.
Move axis 3 to minimum position and push any button.
Hold ... OK.
Move axis 3 to center position and push any button.
Hold ... OK.
Move axis 3 to maximum position and push any button.
Hold ... OK.
Move axis 4 to minimum position and push any button.
Hold ... OK.
Move axis 4 to center position and push any button.
Hold ... OK.
Move axis 4 to maximum position and push any button.
Hold ... OK.
Move axis 5 to minimum position and push any button.
Hold ... OK.
Move axis 5 to center position and push any button.
Hold ... OK.
Move axis 5 to maximum position and push any button.
Hold ... OK.
Move axis 6 to minimum position and push any button.
Hold ... OK.
Move axis 6 to center position and push any button.
Hold ... OK.
Move axis 6 to maximum position and push any button.
Hold ... OK.
Setting correction to:
Correction for axis 0: broken line, precision: 0.
Coeficients: 127, 127, 4227201, 4194176
Correction for axis 1: broken line, precision: 0.
Coeficients: 127, 127, 4227201, 4194176
Correction for axis 2: broken line, precision: 10.
Coeficients: 131, 131, 2147483647, -536854528
Correction for axis 3: broken line, precision: 0.
Coeficients: 127, 127, 2147483647, 2147483647
Correction for axis 4: broken line, precision: 0.
Coeficients: 127, 127, 2147483647, 2147483647
Correction for axis 5: broken line, precision: 0.
Coeficients: 0, 0, 536854528, 536854528
Correction for axis 6: broken line, precision: 0.
Coeficients: 0, 0, 536854528, 536854528
Next time I did:
jscal -c /dev/input/js0 gave me the following output. Axis 0+1 (0/255) & 5+6 (-1/+1) were responsive. None of the others.
Hold ... OK.
Move axis 6 to maximum position and push any button.
Hold ... OK.
Setting correction to:
Correction for axis 0: broken line, precision: 1.
Coeficients: 127, 127, 4227201, 4194176
Correction for axis 1: broken line, precision: 1.
Coeficients: 127, 127, 4227201, 4194176
Correction for axis 2: broken line, precision: 10.
Coeficients: 128, 130, -268427264, -268427264
Correction for axis 3: broken line, precision: 0.
Coeficients: 127, 127, 2147483647, 2147483647
Correction for axis 4: broken line, precision: 0.
Coeficients: 127, 127, 2147483647, 2147483647
Correction for axis 5: broken line, precision: 0.
Coeficients: 0, 0, 536854528, 536854528
Correction for axis 6: broken line, precision: 0.
Coeficients: 0, 0, 536854528, 536854528
Any help is welcome :)
ciaoMao
Last edit: marco 2017-11-14
Hi Alexandre,
any answer is a good answer, even if you tell me, that I am on my own with that problem. Dont worry, thats fine.
Cheers
ciaoMAO
Hi Alexandre,
First thanks for this SW! Only software i have found, capable on mapping two individual joystics as one in retropie.
Question: How do you mapp dual axis as buttons?
I try to mapp a SNES USB Joypad together with Microsoft sidewinder Steering Wheel in order to use with Retropie. I want to use this for analog steering in Grand Turismo II for psx.
The PSX gamepad have digital buttons for up/down/left/right, while the SNES USB have dual axis. Also, i want to use the Steeringwheel & pedals for analog control.
So far, i have not gotten the axis from SNES USB pad to work as buttons. I have used
jstest --event /dev/input/js0 to 2
to verify functionality.Do you have any ideas how to set up SNES axis to be accepted as 4 buttons?
Also, i have tried in several map files to get all three axis to work from SideWinder Racingwheel, but only two seam to work. I have used
jstest --event /dev/input/js0 to 2
here also to verify that all three axis is working when loadmap program is not running, and only two axis is woking when running loadmap.loadmap file:
Great work Alexandr this is excellent!
For anyone having trouble with getting HAT buttons working: Running 'jstest /dev/input/js0' indicated the hats should be axis 3 and 4. After not getting many configuration attempts to work anything to work ended modifying source code to find out what axis is in play. Linux Joystick Mapper is reading the hat in as axis 16 and 17 (CH products joystick). Another issue is the three values read in are -1, 0 and 1. I couldn’t get the mapping to work so I added this code to convent the hat to normal axis values then the rest of the code was happy.
Added to start of routine process_axis in events.c
(commented out debuging info can be removed, maybe of use while trying to setup)
hope this saves some time.
As per previous comments the axis command to map keys is broken so you will need to map joystick to program and trigger buttons from there, example;
if (js0.a[17]==0) {
press("e");
release("e");
};
if (js0.a[17]==255) {
press("r");
release("r");
};
Thanks for the debugging code Stephen, and also for sorting out the Hat- functionality.
With the debugging code, I managed to sort out what axis was used, and also the values out. The PSX emulator expected 32767+/- so i had to scale them.
I added a Code file for scaling and digital conversion. After that, it worked :)
get a positive value for acceleration
USB Button
USB Gamepad Left-Button
USB Gamepad Right-Button
USB Gamepad Up-Button
USB Gamepad Down-Button
USB Gamepad A-Button
USB Gamepad B-Button
USB Gamepad X-Button
USB Gamepad Y-Button
USB Gamepad L-Button
USB Gamepad R-Button
USB Gamepad Select-Button
USB Gamepad Start-Button
MS Sidewinder Racing Wheel
SteeringWheel axis
a[0]=(js1.a[0]);
Break pedal
a[1]=(js1.a[1]);
Gas Pedal
a[2]=(js1.a[2]);
MS Sidewinder A-Button
MS Sidewinder B-Button
MS Sidewinder C-Button
MS Sidewinder X-Button
MS Sidewinder Y-Button
MS Sidewinder Z-Button
MS Sidewinder L-Button
MS Sidewinder R-Button
~~~
Hey all you wonderful helpful people at sourceforge. I've got the nintendo joy-cons connected both simultaneously via bluetooth.
It's been quite the adventure discovering that I needed
hciconfig hci0 piscan
in rc.local to get both controllers to stay connected.Then I tried several different joystick mappers to get the buttons working. Linux joystick mapper is the first one I've had any luck with.
so according to jstest my keys 0-15 but I had to add 16 to get any of the keys to show up. for example
button vendor=0x057e product=0x2006 src=0 target=kbd button="k"
would turn intobutton vendor=0x057e product=0x2006 src=16 target=kbd button="k"
and then it would work.This worked too map every key with the exception of the axis's on the joy-con's. According to jstest they were mapped to
4 and 5 so 4 would show up as 0 at a rest -32764 at far left and a positive value of 32764 at far right.
I've tried setting this up in the following ways to get it working with no success. It's the last thing I need to figure out and I can't get it working.
I've tried:
and I've tryied everything in between including every src between 0 and 34
Does anyone have any ideas or hints as to what I may be missing here?
Last edit: Christopher 2018-02-02
ok. here is some answers to what one can find in the previous 4 pages :-)
what I am doing:
combine a joystick and a rudder pedal.
that means eliminating the rudder from the joystick, and use the rudder pedal instead.
the mapping is broken:
axis 0 and 1 map to 0 and 1 ( x and Y)
axis 2 is axis 5, and you map it to 2 ( z or rudder )
axis 2 is axis 6, and you map it to 3 ( throttle, ussually )
hat X is 16 and you map it to 4
hat Y is 17 and you map it to 5
these numbers (map it to # ) correspond to a "normal" joystick.
check with jstest /dev/input/js<mapper virtual="" stick="" #="">
from your distro on the virtual joystick.
you will see your rudder that is normally at #2 has now become #5.
alexandre's jsinfo works, but is (on my core i7) sluggish, does not react very promptly.
buttons map correctly as far as I know ( I got 12, 0 to 11 )
force feedback: it sort of works, but didnt find out exactly what works and what not.
check my post.
2 = #5 (rudder)
3 = #6 (throttle)
4 = #16 (hatX)
5 = #17 (hatY)
**
maybe this is helpful for the problems people run into with this tool.
the trouble sits mostly in the axis. the buttons are mapping straight forward.
example:
I am mapping two sticks into 1. (joystick and pedals)
this requires the rudder from stick 1 to be replaced by the rudder (pedals) of stick 2.
normal joystick is laid out like this:
0 X
1 Y
2 Rudder
3 throtle
4 hatX
5 hatY
In the virtual Joystick axis:
0 = x, no problem
1 = y, no problem
2 becomes 5.
3 becomes 6.
the hatx and haty becomes 16 and 17
mapping these like so:
0 = 0
1 =1
5 =2
6 = 3
16 = 4
17 =5
to get a normal mapping, does not work.
the 5 => 2 is not recognized as a rudder
and the 6=> 3 is not recognized as a throttle
the hats do not work.
the solution to this is as follows:
map 1 on 1:
0 = 0
1 =1
5 =5
6 = 6
16 = 16
17 =17
and then, to get a normal 0,1,2,3,4,5 joystick mapping:
use jscal.
jscal modifies the driver in the kernel, so no performance penalty.
jscal can switch around the axes to any position you like.
in our case, you want 5 => 2, 6 => 3, 16 => 4, 17 =>5
so the JoyMAP joystick is programmed as the last step with jscal like so :
sudo jscal -u 18,0,1,5,6,16,17,2,3,8,9,10,11,12,13,14,15,4,7,12,256,257,258,259,260,261,262,263,264,265,266,267 /dev/input/js0
[edit]
be careful : if you e.g. map 6 => 3, you must NOT map the 6 again: jscal reads from left to right,
your 6 will be remapped to the last assignment, away from 6=>3 to 6 =>whatever.
So if you have 0,1,5,6,16,17, as "real axis that exist" you cannot use these numbers to fill the
holes you left at 5,6,16 and 17: (17 sits now at 6, so it would be intuitive to swap 6 to 17.
But you just assigned 6 to 4, and it has to stay there !!
so I put 7 there, because that is an axis that does not exist in real hardware and was unused.
[/edit]
explanation:
18 = number of axes. after that :
0,1,5,6,16,17,2,3,8,9,10,11,12,13,14,15,4,5,
is the mapping of the actual axis # in order of numbering.
so, 0,1 changes nothing,
5,6 are in position 2 and 3. so 5,6 will be mapped on 2 and 3 ( the rudder and the throttle.
NOTE: the real 2 and 3 must now be mapped on "unused locations" , in this case I chose 6 and 7, as to not confuse the driver !!!!
same for the hatx and haty : 16 and 17 map on 4 and 5, so , position 16 and 17 are now 4 and 5
after the 18 axes, comes a number denoting the number of buttons. 12 in my case.
buttons number from 256 ( the high byte in the driver, no doubt...)
Proper order of doing this is important:
first load the virtual joystick
then use jscal to put the axes in the proper position.
with jscal -q you can store the command that would configure the stickas it is in its current state.
put it in a script, for easy restore.
WHY the joymapper code is mangling the axes, I do not know. I suppose the characterization of each axis is not copied along with the remapping of the axis in question.
hope this helps
[edit]
I tried the combined joysticks into the joymapper virtual joystick at js0
and then NOT remap the axis into 0,1,2,3,4,5,6
Turns out that it works just as well: hats are hats, rudders are rudders, and throttles are throttles.
I do not know how this works for linux games.
I am using this in Wine, for old windows flight simulation games.
it turns out, that there is no need to map (with jscal) the hats, rudder, throttle into "proper" consecutive places without empty slots in between.
all 3 windows games happily use the number 5 and 6 for rudder/throttle, and are having no problem with the hatx and haty sitting at 16 and 17........
they do not care about 2,3 and 6 upto 15 being "empty"
so, just mapping 1 on 1 works just fine, at least for Wine.
[/edit]
My confusion is caused by jscal versus jstest :
jstest shows active available axis and hats etc. and renumbers them. That is visual, it does nothing with the actual structure in the driver....
Looks convenient, but very confusing when nr 16 becomes nr 5 without any info that that is happening.
jscal -q <some device=""> shows what the "real" slot-number is of any existing axis in the device
Last edit: rensg 2018-05-19
hi Alexandre,
thanks for this amazing piece of software, It really saved me a lot of pain and time in setting up my joystick for emulating mouse under DosBox.
I attach here three different map files (tested) to use with the excellent Logitech Wireless Game pad F710 https://tinyurl.com/y7oymfz4
They are well commented, should be a breeze to customize them for your own use.
Please note that they will likely work with Logitech Wireless Game pad F710 only
================================================================
joypad.map - configured to use as joystick/keyboard emulation for both left/right sticks (will not emulate mouse)
joy-mouse.map - configured to emulate a mouse (right analogue stick) and joystick/keyboard (left stick). This is optimal for games using both keyboard / mouse
mouse.map - configured to simulate mouse only (both left and right sticks are used as mouse)
================================================================
Cheers guys!
TZF
Last edit: TZF 2018-11-15
Second attachment:
joy-mouse.map - configured to emulate a mouse (right analogue stick) and joystick/keyboard (left stick). This is optimal for games using both keyboard / mouse
Third attachment:
mouse.map - configured to simulate mouse only (both left and right sticks are used as mouse)
Last edit: TZF 2018-11-12
i know its a bit outdated, but here is my map for Worms Reinforcements (1996) for "Dragonrise inc, generic usb joystick", similar PS2 gamepad. Thanks to all of you!
I have just discovered this project while setting up a number of dos games for RetroPie, and it looks very good.
Is it possible in any way for the axis buttons to behave like the cursor keys (that bit I have working), but behave differently, e.g. like a mouse when another button is held down?
I have a basic SNES style controller and for one game this would kill off the need for the wireless mouse.
Hi Dave,
The "shift" button can be used to change behaviour based on whether that button is pressed or not. However, that only applies to buttons and not to axes.
You can achieve that effect by writing a "script". Use the "code" directive (to specify the program to execute) as well as "script" directives (to tell joymap how it should present your joysticks to the program) and then you can implement the switch between buttons an axes in code. Perhaps something like:
You can then map the output of the virtual joystick into actions.
Note that this will require some effort to make sure it returns to a decent state whenever a button is pressed or released., but it can be done.
Thanks, I will try the shift button first. The game I have been working with is Worms, where you use the mouse to pan round the screen to decide who to shoot then it is all keyboard from there. Using shift and the ABXY buttons to pan is no big deal.
I might try the code too then post the results of both here for others to find.