Page 1 of 1

USBJoystick 0.23

Posted: Wed Aug 26, 2026
by richw
USBJoystick is a USB joystick driver for RISC OS 5. It supports USB HID-compliant joystick (or gamepad, or steering wheel etc.), including the XBOX 360 wired and wireless controllers. It provides the legacy Acorn, RTFM and SerialPort SWI interfaces, so existing games can be used with modern controllers.


What’s new?
  • Settings (such as stick and axes mappings) can be persisted
  • Some new SWIs are added for device/axes/button detection - slightly different to 0.22
  • A prototype 'JoySetup' tool (intended to become a Boot/Configure plugin)
  • Basic mouse and keyboard mapping should be working now (was previously iffy)
  • The full source code has an official home

Download

Version 0.23 (binary) is attached to this post.

Source is here: https://gitlab.riscosopen.org/rwalker/usbjoystick

Source for the JoySetup plugin is here: https://gitlab.riscosopen.org/rwalker/joysetup


Requirements

You need a RISC OS 5 machine with USB hardware. I have only tried a Pi model B+. In theory, any USB HID-compliant joystick will work, but again, I have only tried what I have:
  • a USB-Atari interface, with an old Atari joystick, and a Chinese knock-off MegaDrive pad
  • a wireless XBOX360-style controller (a Chinese clone, not a real Microsoft one!)
For any *commands, it is particularly useful if you have the LineEditor module installed. If you don’t have this, I would recommend you get it and stick it in your Boot PreDesk directory. You’ll wonder how you ever lived without it! You can grab the module from here:
https://github.com/philpem/LineEditor

Please make sure you don’t have any unsaved data before trying this module!

SparkFS (or similar) will be needed to open the attached zip file.


Starting

The zip file contains a single RISC OS module, USBJoystick. Just double-click it. You can copy it to Choices:Boot.PreDesk if you want it to run at boot-up.

You can also run the !JoySetup application to try out the Boot/Configure plugin. If you are really keen, you can copy it within your !Boot directory to make it appear when you run Boot/Configure (like all the other plugins).

The 'utils' directory contains a couple of BASIC test applications:
  • ADCTest: tests the I/O module ADC OSByte interface)
  • AcornTest: tests the Acorn 8-bit and 16-bit Joystick_Read SWI
  • Acorn2Test: tests the new prototype device read SWIs
  • RTFMTest: tests the RTFM interface - this is not currently usable
  • SerPortTest: tests the Serial Port (Vertical Twist) Joystick_Status SWI
You can use these from within a Task Window or by double-clicking from the Desktop. They will allow you to verify your joystick configuration without going to the trouble of loading a game.


Joystick discovery/enumeration

Open a Task Window (CTRL-F12) and type '*USBJoystick_List’. You should see some information on whatever joystick(s) you have plugged in. Each joystick is given an id number, starting from zero.

If you don’t see your joystick, then USBJoystick has not been able to detect it (can you see it if you use the OS command, '*USBDevices’?).


Enumeration

Joysticks will be discovered when the module starts. If you connect a joystick later on, it should be automatically detected (without restarting the module). Similarly, if you remove a joystick, the module will stop talking to it.


Mapping

The classic Acorn and Serial Port Joystick APIs refer to joysticks by a joystick number (0 or 1, for player 1 and 2 respectively). Note that the RTFM and Serial Port APIs only support one or two joysticks, but the Acorn API can support many more.

Each joystick number can offer two directional axes, typically up/down (Y) and left/right (X). A modern USB joystick will have multiple analogue axes (X, Y, Z, RX, RY, RZ) and separate digital inputs (DPAD or HAT switches). The desired USB axes need to be 'mapped' to the legacy number, X axis and Y axis.

You can map up to 16 buttons, but these will only work independently with the Acorn Joystick APIs. Games using the Serial Port or RTFM API will see a 'fire' when any of the buttons are pressed.

You can see the mapping with *USBJoystick_Mapped.


Automatic mapping

USBJoystick tries to automatically map the USB stick, axes and buttons across to the legacy items. The stick numbers will be assigned based on the order the USB devices are identified. If your joystick has a DPAD or HAT switch they will be mapped to the Serial Port, RTFM and Acorn 8-bit X and Y axes. If you have analogue X and Y axes, they will be mapped to the Acorn 16-bit X and Y axes. The buttons will be mapped in their order they the controller reports them - usually the first one reported is the primary.


Manual mapping

If the automatic mapping is not to your satisfaction, it can be adjusted with a number of *commands: *USBJoystick_MapStick, *USBJoystick_MapAxes8, *USBJoystick_MapAxes16 and *USBJoystick_MapButtons. Use the help to discover the exact syntax, e.g. *Help USBJoystick_MapStick will show you how to use the stick mapping feature.

You need to test your joystick to determine which axes and button you want to use. Type 'USBJoystick_Read 0' (or whatever joystick id you want). You should see some raw data showing the state of each axis and button. If you don’t touch the joystick, they will all be at their rest positions. Move the joystick up, and whilst holding that position, enter the read command again. Compare the two read outputs: you should be able to spot the value changing on one of the axes. This will be the Y-axis. Make a note of the axis number.

Repeat the above for identifying the X-axis, and each button. At the end of the process, you should know for each joystick id, the x and y axes numbers, and the primary button number. To map these up to the old Acorn/SerialPort API, you need to use the commands mentioned at the beginning of this section.

If any of your axes are working the wrong way around (e.g. up is down and down is up) then you can use the *USBJoystick_Flip command to invert the direction.

Please note that the mapping is not saved anywhere - it is just remembered in RAM. If you unplug the joystick, kill the USBJoystick module, or reboot your machine, the mapping will be lost. Once you have it figured out, you may wish to create an obey file which will set it up again for you.


Acorn I/O Podule Analogue to Digital converter

USBJoystick can emulate the ADC converter found on the I/O podule. It hooks into OSByte 128, so software using this SWI (including BASIC’s ADVAL function) will work. You can map an axis, or part of an axis, to an ADC channel, and a pair of buttons for fire. Please investigate the *command help: there is some mapping required.

The partial mapping is useful for configurations like a single Y axis (0 for middle, +32768 for top, and -32767 for bottom), where you want to map ADC Channel 0 to ‘up’ (so 0 to 32768 will be translated to 0 to 65520) and Channel 1 to ‘down’ (so 0 to -32767 will be translated to 0 to 65520).


Using the Joystick

Once you have mapped, you can use any software which supports the Acorn (SWI Joystick_Read) or Serial Port (SWI Joystick_Status). The USB Joystick driver module will transform the USB data into a format for those SWIs, and respond to their requests. With the help of ADFFS, games which use the RTFM API should also function.

I have tried some of the games from this web site: James Pond and SWIV work over the Serial Port SWI, and Zool works over the Acorn SWI.


Testing

Obviously, this thing is far from finished. It clearly needs more testing: one machine, two USB joysticks, and three games doesn’t really cut it! :)

All feedback is welcome.


Technical matters

If you have any problems with the module, it would be helpful if you could run Reporter before you run the module. If Reporter is active, some debugging guff will appear in Reporter’s log. This may help me! Reporter is available here: http://www.avisoft.f9.co.uk/Reporter.htm

The *command *USBJoystick_Debug 0 (replacing 0 for your joystick id, or removing it entirely to see all) may also provide useful information for me.

The output from Colin Granville's USBDescriptors may be useful.


Acknowledgements

Jon’s efforts with JASPP itself was my inspiration for developing this (obviously, this is tiny effort in comparison!). Also, many thanks to the following people over on the ROOL forums who offered advice and put up with my silly questions: Jeffrey Lee, Rick Murray, Stuart Swales, Colin Granville, Simon Birtwhistle, and Chris Mahoney. Thanks to James Peacock for EtherUSB, and Colin Granville for USBDescriptors. The code uses components from NetBSD and XMAME. There are further notes in the source code.


Todo: Refactoring
  • Listen for service calls from USBDriver Starting/Dying
  • Determine correct error-handling strategy for module_finalise()

Todo: Features
  • Support SerialPort 'stir', 'flag A' and 'flag B' - extra buttons/mappings?
  • Extend JoySetup to cover mouse, keyboard and ADC emulation options