# announcing emulators/joytran



## beyert (Apr 4, 2012)

Hi everyone,

Last July, I wrote a program called Joytran, which translates joystick events to keyboard and mouse events.  It has been available in the ports tree (emulators/joytran) since 2011 October, but it occurred to me that my target audience of *BSD users (specifically FreeBSD) are likely unaware of its existence.

Such a program is important for people who like to play games or use a joystick in emulators/wine, emulators/virtualbox-ose, or applications that use linux emulation.  Due to the fact that devel/linux-js does not work on FreeBSD versions 8.x or newer, [1] I became motivated to write this program.  It effectively allows you to create customizable joystick support for any application that uses the keyboard and mouse, and may be closed when you want to run an application that has proper joystick support, such as emulators/zsnes.

The alternative which I typically see people mention on BSD message boards is "native" Xorg joystick to keyboard/mouse translation, which I found to be very limiting.  It does not allow to change profiles on the fly without restarting the Xserver, [2] fails to recognize joystick "hats" properly, and performs poor axis translation. [3]

Previously the documentation was very minimal, [4] but now most aspects of the program are thoroughly documented, and in version 0.8.7, it is no longer necessary to write your own joystick profiles, thus making the program far easier to use than in prior versions.

Currently, it has been tested with PlayStationÂ®2 joystick adaptors, but I believe that it should work with most types of joysticks with ease.  Anyway, I'm eager to hear about any bugs or issues that people have with the program, so if you have any problems, questions, suggestions, critiques, or death threats, please send me an email message. (I will set up a mailing list as well if there is sufficient demand)

There is a fossil repository as well as a FreeBSD port (emulators/joytran) available.

Regards,
Tim

--------------------------------------------------------------------------------

[1] This is due to the change to the new USB stack.  Since devel/linux-js is a non-trivial application, the maintainer of that software or someone who is experienced in both joystick APIs would need to rewrite it.

[2] Hotplug should be possible, but I couldn't figure out how to get HAL working; it is not clear to me if HAL hotplug functionality ever worked on FreeBSD for joysticks.  It is also deprecated by our friends at freedesktop.org, which destroyed my incentive to understand HAL.

[3] It doesn't handle diagonal movement gracefully, whereas emulators/joytran does.

[4] In fact, the only mention of the program that I found on google was in the PC-BSD forums where a user stated that they were unable to get the program working and moved on.  Sorry about that, :e hopefully it should be easier to use now!


----------



## Zare (Apr 4, 2012)

Thank you for heads-up. I could use this program, since I have a dedicated FreeBSD machine running DosBOX / ZSNES  The plan was to program a nice graphical menu and use joystick for control. However since most DOS games require keyboard, I fell back to running full screen xterm. If I ever revert to original plan, I'll remember your work


----------



## beyert (Apr 5, 2012)

Cool, well if you try it out and run into problems, don't hesitate to contact me.


----------



## lme@ (May 2, 2012)

Hi Timothy,

I tried joytran without any luck with a PS3 controller connected via USB.
No events are shown in xev.

Using the default-one_player config file:

```
joytran -b -v -p default-one_player
using profile in file: /usr/local/share/joytran/profiles/default-one_player
running in background
Initializing SDL.
SDL initialized.
joy 0 configured: ready
```

Output of *usbhidctrl*:


```
usbhidctl -f /dev/uhid0 -r
Report descriptor:
Collection type=Application page=Generic_Desktop usage=Joystick
Collection type=Logical page=Generic_Desktop usage=Joystick
Input   rid=1 size=1 count=1 page=Button usage=Button_1, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_2, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_3, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_4, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_5, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_6, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_7, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_8, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_9, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_10, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_11, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_12, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_13, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_14, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_15, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_16, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_17, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_18, logical range 0..1, physical range 0..1
Input   rid=1 size=1 count=1 page=Button usage=Button_19, logical range 0..1, physical range 0..1
Collection type=Physical page=Generic_Desktop usage=Pointer
Input   rid=1 size=8 count=1 page=Generic_Desktop usage=X, logical range 0..255, physical range 0..255
Input   rid=1 size=8 count=1 page=Generic_Desktop usage=Y, logical range 0..255, physical range 0..255
Input   rid=1 size=8 count=1 page=Generic_Desktop usage=Z, logical range 0..255, physical range 0..255
Input   rid=1 size=8 count=1 page=Generic_Desktop usage=Rz, logical range 0..255, physical range 0..255
End collection
Input   rid=1 size=8 count=1 page=Generic_Desktop usage=Pointer, logical range 0..255, physical range 0..255
[...]
Input   rid=1 size=8 count=1 page=Generic_Desktop usage=Pointer, logical range 0..255, physical range 0..255
Output  rid=1 size=8 count=1 page=Generic_Desktop usage=Pointer, logical range 0..255, physical range 0..255
[...]
Output  rid=1 size=8 count=1 page=Generic_Desktop usage=Pointer, logical range 0..255, physical range 0..255
Feature rid=1 size=8 count=1 page=Generic_Desktop usage=Pointer, logical range 0..255, physical range 0..255
Feature rid=1 size=8 count=1 page=Generic_Desktop usage=Pointer, logical range 0..255, physical range 0..255
[...]
Feature rid=1 size=8 count=1 page=Generic_Desktop usage=Pointer, logical range 0..255, physical range 0..255
End collection
Collection type=Logical page=Generic_Desktop usage=Pointer
Feature rid=2 size=8 count=1 page=Generic_Desktop usage=Pointer, logical range 0..255, physical range 0..255
Feature rid=2 size=8 count=1 page=Generic_Desktop usage=Pointer, logical range 0..255, physical range 0..255
[...]
Feature rid=2 size=8 count=1 page=Generic_Desktop usage=Pointer, logical range 0..255, physical range 0..255
End collection
Collection type=Logical page=Generic_Desktop usage=Pointer
Feature rid=-18 size=8 count=1 page=Generic_Desktop usage=Pointer, logical range 0..255, physical range 0..255
Feature rid=-18 size=8 count=1 page=Generic_Desktop usage=Pointer, logical range 0..255, physical range 0..255
[...]
Feature rid=-18 size=8 count=1 page=Generic_Desktop usage=Pointer, logical range 0..255, physical range 0..255
End collection
Collection type=Logical page=Generic_Desktop usage=Pointer
Feature rid=-17 size=8 count=1 page=Generic_Desktop usage=Pointer, logical range 0..255, physical range 0..255
Feature rid=-17 size=8 count=1 page=Generic_Desktop usage=Pointer, logical range 0..255, physical range 0..255
[...]
Feature rid=-17 size=8 count=1 page=Generic_Desktop usage=Pointer, logical range 0..255, physical range 0..255
End collection
End collection
Total   input size 49 bytes
Total  output size 49 bytes
Total feature size 49 bytes
```

Do you have an idea?


----------



## beyert (May 3, 2012)

Wow, I didn't even know that FreeBSD supported PS3 controllers.  I'll test it with my PS3 controller tonight.

Does it work properly with regular SDL games like emulators/zsnes or something else SDL based?

Also, presuming that it does work, you will need to adjust the profile to add the axis and/or hats as needed for the additional sixaxis controls, and the PS3 button.  At the moment, I have no idea what buttons 14-19 are used for, but I'll look into it.

Tim


----------



## lme@ (May 3, 2012)

I don't know if they're working, I just plugged mine in and it was presented as a uhid device, so I gave joytrans a try.


----------



## beyert (May 5, 2012)

I think that SDL joystick support is broken for version 1.2.15 of devel/sdl12 on 9.0-RELEASE, on two of my computers.  I was unable to use any joystick in any SDL applications on both of my 9.0-RELEASE boxes, so I tried reverting to the cvs revision of 2012-01-15 of the port, and all of my SDL applications (emulators/joytran, SDLJoytest-GL, emulators/zsnes and so on) started working again.

If anyone alse is experiencing this problem, issue the following commands (it might be possible to get a slighly newer revision, but this worked for me, so I didn't bother):

tcsh/csh:


```
> setenv CVSROOT :pserver:anoncvs@anoncvs.tw.FreeBSD.org:/home/ncvs
> cvs -Qf export -d sdl12 -D "2012-01-15" ports/devel/sdl12
```

bourne shells:


```
$ export CVSROOT=:pserver:anoncvs@anoncvs.tw.FreeBSD.org:/home/ncvs
$ cvs -Qf export -d sdl12 -D "2012-01-15" ports/devel/sdl12
```

Unfortunately, when I tried my PS3 DualShock 3 controller, it did not work for any SDL applications (SDLJoytest-GL or emulators/joytran), even after I reverted to SDL 1.2.14.  I'd like to fix support for it in SDL (or FreeBSD, since it might a lower-level hardware/driver issue) at some point, although it might not be for a while.


----------



## sidetone (Jun 12, 2022)

Great program! I was able to use Joytran to get HID events on my gamepad from wired USB connections. It's relevant about a decade later for newer HID drivers.

Thread howto-enabling-multimedia-keys-gamepads-joysticks-for-desktop-usbhid.84464 is over hgame(4) and usbhid.


Late edit: Earlier, I misremembered that it was hcidump, that I used over Bluetooth events.


----------

