USB Joystick driver

Discuss development specific to the Pi version of ADFFS
Post Reply
richw
Posts: 84
Joined: Sat Sep 14, 2013 9:05 pm

USB Joystick driver

Post by richw » Sat Mar 24, 2018 11:01 pm

Hi all,

As previously mentioned, here is an alpha test version of my USB Joystick driver module (scroll to bottom of post for download link). Quick instructions follow.


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:
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/jaylett/zap/blob/61a ... itor%2Cffa

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

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


Starting

The zip file contains a single RISC OS module, USBJoystick. Just double-click it. The 'src' directory may interest you if you have the ROOL DDE.

Aso in the 'src' directory is a 'utils' directory, which contains a couple of BASIC test appliations. They test the SerialPort and Acorn interfaces (just as games would) so you can use them to check your joystick is detected and mapped correctly without running 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. Note the ‘mapped to’ lines, which should be empty (-).


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) and they support two directional axis, typically up/down (Y) and left/right (X). This needs to be 'mapped' to the capabilities of your USB joystick.

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 ‘*USBJoystick_Map'. Help is available, so ‘*Help USBJoystick_Map’ will tell you the formal definition of the command.

For my Atari joystick, the USB Joystick id is 0 (because it’s the first one I plugged in), axis 2 is X, axis 3 is Y, and button 1 is fire. If I want to map this up to what we would call ‘joystick 1’ in the old days, then I need to enter: '*USBJoystick_Map 0 0 2 3 1’. Then if I do a ‘*USBJoystick_List 0’ to confirm things, I can see the mapping information at the bottom of the output.

As of version 0.7, you can map up to 8 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.

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.


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.

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. Later, I’ll post up my ‘to do’ list. 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) may also provide useful information for me.

The output from Colin Granville's USBDescriptors output 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
  • Do we really need joy_index to be a global?
  • Implement releasing of memory in clean_joystick_data_item()
  • Determine correct error-handling strategy for module_finalise()

Todo: Features
  • Support multiple buttons in the mapping DONE IN 0.7
  • Support SerialPort 'stir', 'flag A' and 'flag B' - extra buttons?
  • Decide if we need ability to reverse an axis in the mapping
  • Emulate 16-bit Acorn Joystick_Read response DONE IN 0.7
  • Emulate RTFM joystick API (based on Econet hardware peeks) DONE IN 0.6 (with ADFFS)
  • Emulate Acorn I/O podule API (ADVAL and associated OSBYTEs)
  • Save settings into Choices$Write and read back on init
  • Load settings via USB alias system (used by !Printers). Would it be useful?
  • Consider auto-assigning lagacy joystick numbers as devices are discovered - useful?
  • Allow Joystick actions to be mapped to keypresses or mouse moves
  • Formalise an SWI interface for device enumeration and configuration. This would allow a Configure plug-in to be developed.

Download

The latest release is attached to this post.
Attachments
USBJoystick007.zip
(174.79 KiB) Downloaded 7 times
USBJoystick006.zip
(155.24 KiB) Downloaded 55 times
Last edited by richw on Thu Sep 13, 2018 9:07 am, edited 14 times in total.

grannyg
Posts: 17
Joined: Fri Dec 13, 2013 3:47 pm

Re: USB Joystick driver

Post by grannyg » Sun Mar 25, 2018 10:40 am

Just tried it on a RPi 3B+ with SWIV. Works great with a Competition Pro and a cheapo Snes Clone.
Seems really responsive.
Initially couldn't get the usbjoystick_read to show any changes. Had to remove !USBHID from !Boot. It also caused aborts when booting.

Adding the USBJoystick module to PreDesk works OK too once !USBHID was removed from !Boot.

richw
Posts: 84
Joined: Sat Sep 14, 2013 9:05 pm

Re: USB Joystick driver

Post by richw » Sun Mar 25, 2018 10:16 pm

Ah, yes. I shall have to try that (I have the freeware version somewhere).

USBJoystick scans all connected devices, and anything that it decides looks like a joystick, it will try and talk to. Maybe HID is trying to do similar? I cannot recall the error-handling path when it cannot open the stream, so I shall investigate.

Thanks for the feedback.

Regarding your earlier question on the keyboard handling, yes, I am planning on adding more *commands so you can map a movement to a fake key press. So keyboard-only games could become controlled by joystick. Same idea for the mouse.

richw
Posts: 84
Joined: Sat Sep 14, 2013 9:05 pm

Re: USB Joystick driver

Post by richw » Tue Mar 27, 2018 9:49 pm

I have just upped the version to 0.03.

The second stick on the Joystick_Status SWI was corrupt, and I have tried to indicate if the endpoint could not be opened on *USBJoystick_List

The archive also includes the source code.

JonAbbott
Posts: 2013
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex

Re: USB Joystick driver

Post by JonAbbott » Tue Mar 27, 2018 10:31 pm

Emulate RTFM joystick API (based on Econet hardware peeks)
I can modify ADFFS to pass reads/writes to the Econet interface to your code if it's any use? At the time it handles them it's in Abort mode with IRQ disabled, so you won't be able to issue any SWI, but assuming it's just translating cached values it will work.

Is there any documentation on the RTFM interface? I'll need to know which addresses it's on.

JonAbbott
Posts: 2013
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex

Re: USB Joystick driver

Post by JonAbbott » Wed Mar 28, 2018 12:51 pm

JonAbbott wrote:
Tue Mar 27, 2018 10:31 pm
Is there any documentation on the RTFM interface? I'll need to know which addresses it's on.
I've found the RTFM drivers here, based on which I've modified ADFFS so the check for the RTFM Joystick Interface works.

It appears to use bits 4..0 across two ports @ 33A0004 and 33A0008. From what I can gather, each port is a separate Joystick with bits defined as follows:

Code: Select all

Bit / Value
0     Right
1     Left
2     Down
3     Up
4     Fire
If I read the joystick state via Joystick_Read at VSync and set the two registers accordingly, will that be sufficient to work with your Module?

JonAbbott
Posts: 2013
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex

Re: USB Joystick driver

Post by JonAbbott » Wed Mar 28, 2018 4:39 pm

After much faffing around I've finally manage to get the 0.03 source to compile under DDE24 - had to create aliases for some commands and duplicate path variables, not to mention hunt down FAppend!

Anyhow...assuming the resultant Module is ARMv7 compatible, I tested the two HID devices I have on a Pi3. Sadly neither show up under *USBJoystick_List.

The first I tried was a Microsoft Force Feedback Joystick, which identifies as:

Code: Select all

USB$Device_00_00_00_045E_001B_-1_-1_0A00_USB5 : 5
USB$Device_03_00_00_045E_001B_01_00_0A00_USB5 : 5 0 0
The second one was a Thrustmaster Force Feedback Steering Wheel, which identifies as:

Code: Select all

USB$Device_00_00_00_06F8_0004_-1_-1_0100_USB6 : 6
USB$Device_FF_FF_FF_06F8_0004_01_00_0100_USB6 : 6 0 0
I have however made the changes to ADFFS to translate the Acorn Joystick interface to RTFM...just need to test it, if I can find a Joystick that will show up.

richw
Posts: 84
Joined: Sat Sep 14, 2013 9:05 pm

Re: USB Joystick driver

Post by richw » Wed Mar 28, 2018 8:36 pm

JonAbbott wrote:
Wed Mar 28, 2018 12:51 pm
I've found the RTFM drivers here, based on which I've modified ADFFS so the check for the RTFM Joystick Interface works.
Ah yes, I knew I’d downloaded them before from somewhere! I vaguely recall looking at the ReadJoy BASIC program. Shame the archive contains the Extend virus.
It appears to use bits 4..0 across two ports @ 33A0004 and 33A0008. From what I can gather, each port is a separate Joystick with bits defined as follows:

Code: Select all

Bit / Value
0     Right
1     Left
2     Down
3     Up
4     Fire
If I read the joystick state via Joystick_Read at VSync and set the two registers accordingly, will that be sufficient to work with your Module?
That sounds reasonable from my glance over the ReadPorts code (ARM assembler isn’t really my thing, though!). It looks fairly similar to the Serial Port’s SWI interface, so I’m sure I can produce the correct data format. The bit which scared me was the hardware probing, where it’s doing all that funky Econet stuff. I guess it can be dumbed down slightly, so as you say, we just need to trap reads from BoardAddr (0x33A0004). Not sure how to do that in a C module, but I’ll ponder it.

I suspect it’s also worth looking at a game itself, as it’s a bit of an assumption that the official test application is representative of the games. :) Mind you, that’s the approach I took for the Acorn and Serial Port SWIs, and it seemed to work OK. I don’t suppose in your archive metadata, you note the joystick status for each game?

richw
Posts: 84
Joined: Sat Sep 14, 2013 9:05 pm

Re: USB Joystick driver

Post by richw » Wed Mar 28, 2018 8:44 pm

JonAbbott wrote:
Wed Mar 28, 2018 4:39 pm
After much faffing around I've finally manage to get the 0.03 source to compile under DDE24 - had to create aliases for some commands and duplicate path variables, not to mention hunt down Append!
Ah yes, I had some fun with FAppend being missing from my DDE (27), and I was going to raise that on the ROOL forums. You’ve reminded me! I was trying to follow the pattern of the shared makefiles etc., using some of the modules in the RISC OS source code as templates for how things should be set up.
Anyhow...assuming the resultant Module is ARMv7 compatible, I tested the two HID devices I have on a Pi3. Sadly neither show up under
*USBJoystick_List.
Shame. Any chance you can run Reporter and observe the output when you start the USBJoystick module? It will only list (and try and talk to) devices that it believes are USB HID compliant, and ‘look like’ gamepads/joysticks. The ‘look like’ algorithm came from XMAME, which apparently uses the same sort of approach Microsoft used in Windows. I am not totally surprised that a steering wheel might be too funky, but you’d think an FF joystick would work (are they quite old?).

I have an Ancient (2005-ish) Playstation 1 pad to USB adaptor, and that doesn’t work at all. It doesn’t provide a HID descriptor.

I have however made the changes to ADFFS to translate the Acorn Joystick interface to RTFM...just need to test it, if I can find a Joystick that will show up.
Ah, so you trap those memory reads, and just issue a Joystick_Read SWI? That should ‘just work’ as they say. I have a feeling converting to Joystick_Status might be even easier.

Vanfanel
Posts: 463
Joined: Mon Sep 16, 2013 12:01 am

Re: USB Joystick driver

Post by Vanfanel » Wed Mar 28, 2018 10:18 pm

My joystick is a PSX original joystick that uses a GreenAsia adapter, very popular around here.
It seems that, according to *usbjoystick_list, it's not recognized... :(
Any chances for it to work? Works on GNU/Linux with no problem on PC, Raspberry Pi, etc...

Post Reply