For responsive controls and high performance gaming, high adapter latency is extremely undesirable. Let's look at why and how it happens and what
can be done to minimize it.
If expressed with words, an adapter works like this:
- At a fixed interval, the adapter polls the controller to detect state changes (buttons, axis, etc).
- When a change is detected, the adapter sends an event to the PC.
- But USB devices are also polled by the PC at a fixed interval. This means that to send the event, the adapter actually has to wait until the next USB poll.
There are two main contributors to latency:
- The controller poll interval: Adapters commonly poll controllers at 16ms intervals. This makes sense as it mimics what most games
do in polling the controller once per video frame. But it also means that if you push fire 1ms after the poll, the adapter will only
know it at the next poll, 15ms later.
- The USB poll interval: For an USB low speed device, the minimum interval is 10ms. Depending on the timing, if the adapter learns
about the button press right after the USB poll took place, the computer won't know about it for another 10ms. In the worst case
scenario, the 15ms latency from point 1 adds to the 10ms, totalling 25ms.
Here is a sequence chart to visualize the above:
The chart clearly shows:
- Latency source 1: The button press occurs, but the adapter knows about it later when it polls the controller.
- Latency source 2: The adapter finally knows about the button press but has to wait for the next USB poll to report it to the PC.
Given the above an obvious solution comes to mind: USB and controller polls both should take place as often as possible. Let's examine both:
- USB polls: This is a simple matter of setting the USB endpoint descriptor bInterval field to a low value. For USB Low speed devices,
the minimum interval is 10ms. For USB Full speed devices, the minimum is 1ms. This adapter, being a full speed device, uses the minimum value of 1ms.
- Controller polls: By default, this adapter polls at 5ms intervals. But this can be changed using the management tool. Setting this to a
very low value does not appear to cause problems with standard controllers, but incompatibilities could arise when using third party controllers or adapters.
It is worth noting that there is another approach to reducing USB poll induced latency by timing the controller polls such that they take place a few
moments before the next USB poll. But with a 1 ms USB poll interval, it's not really necessary.
|Adapter||USB type||Controller poll interval||USB poll interval||Worst case||Comments|
|raphnet gcn64usb v3 (The one on this very page)||Full speed||5ms default||1ms||6ms||If controller poll is configured to the minimum value of 2ms, worst case is only 3ms.|
|raphnet gc/n64 usb v2 (predecessor)||Low speed||4ms||5ms||14ms||Due to the report size, two USB polls are necessary to transmit an event, hence the 14ms worst case instead of 9ms|
|Non-raphnet adapters (for reference)|
|Mayflash dual N64 to USB||Low speed||16ms||8ms||24ms||bInterval = 8ms, controller poll interval verified using an oscilloscope.|
|Mayflash GC (4x) to USB (PC mode)||Full sped||8ms||1ms||9ms||bInterval = 1ms, controller poll interval verified using an oscilloscope.|
Even though the minimum poll interval for an USB low speed device is 10ms, it is possible to cheat and use a lower value. Because it works.
The worst case value given for non-raphnet adapters assumes that no attempt is made to synchronize controller reads with USB polls (i.e. reading the
controller right before the USB poll). If they are doing synchronisation, then the usb poll interval (or a fraction of it depending on design margins) needs to be subtracted from the worst case value.
Since firmware version 3.2.1, there are several modes (or personalities) allowing a more
accurate adapter USB product name to be displayed. For instance, if you built a N64 to USB adapter,
the adapter can now appear as "N64 to USB" instead of "GC/N64 to USB".
Also, since firmware version 3.3.1, there are also two player modes.
Configuring the personality and/or enabling a two payer mode must be done using the gcn64ctl
- Install the adapter management tool. It has a graphical user interface, but command-line
tools will be installed along with it. There will be an entry in the start menu (or the new equivalent
and concept of the day) to open a terminal in the folder where the tool executables are.
- Connect the adapter to configure. Only one adapter should be connected at the time.
- Execute the command with the appropriate mode argument.
# Syntax for configuring an adaptater
gcn64ctl -f --set_mode xx
(where xx must be replaced by the appropriate numerical code)
|Code||Name||Number of players|
|0||GC/N64 to USB v??||1|
|1||N64 to USB v??||1|
|2||Gamecube to USB v??||1|
|16||Dual GC/N64 to USB v??||2|
|17||Dual N64 to USB v??||2|
|18||Dual Gamecube to USB v??||2|
I cannot be held responsible for any damages that could occur to you
or your equipment while following the procedures present on this page.
Also, I GIVE ABSOLUTELY NO WARRANTY on the correctness and usability
of the informations on this page. Please note, however, that the procedures
above have worked in my case without any damages or problems.
Now you cannot say that I did not warn you :)