For compatiblity, my extenmote adapter has to convert
N64 and Gamecube joystick values to match those of a classic controller which has a lower resolution (6 bits
instead of 8 bits). This means that the controllers are not working at their full potential. For many
games I guess it does not matter, but for N64 and Gamecube [1] emulators, it decreases
accuracy and might make the controls feel different or slightly wrong.
To improve the situation, I have implemented new features to make it possible to access
the raw data from the adapted controller. This experiment started in version 1.8 and has
been improved in version 1.9.
So, how is the raw data made available?
Method 1: The adapter appends raw values to the standard classic controller report.
Software unaware of this feature will continue working normally, but the is available
and usable by applications were it is useful. See section New structure
below for details.
Method 2: The adapter normally appears as a Classic controller. However, if a value
of 0x64 is written to register 0x00 after disabling encryption, the extension ID will
be different depending on the connected controller. The reported data is only and exactly
what was received from the controller. Please see below for details.
What game/software make use of the raw data feature?
At the moment, I am not aware of any users of this feature. If your software
use it, please let me know. I would like to list it here.
[1] I'm thinking of Devotion which make it possible to play gamecube titles
on Wii and Wii U without gamecube ports using a Classic controller. Not really an
emulator, but this is exactly where I think raw data access is useful.
The controller ID bytes indicate the type of controller connected and therefore how to interpret the
controller specific data bytes that follows. Possible values are:
0x36,0x34 ('6','4'): N64 controller
0x47,0x43 ('G','C'): Gamecube controller
0x53,0x46 ('S','F'): SNES controller
0x46,0x43 ('F','C'): NES controller
Rumble/Vibration: Writing at byte 6 will eventually control the vibration function. A non-zero
value will turn on the motor, a value of 0 will turn it off. Note that byte 6 will still read 'R' even after
being written to.
Method 2: Extension IDs
A value 0x64 must be written to the adapter at address 0x00 before reading
the extension ID. Refer to wiiuse/io.c:wiiuse_handshake_expansion() in the
example libogc patch.
When the adapter apperas as one of the above extension IDs, the reported data
is in the specific controller format starting right at byte 0. It is not
appended to a standard classic controller structure.
Rumble/Vibration: Writing at byte 8 will eventually control the vibration function. A non-zero
value will turn on the motor, a value of 0 will turn it off.
N64 Controller data
When the controller ID bytes order the extension ID indicates a N64 controller is connected,
the controller specific data is as follows:
Bit
Byte
7
6
5
4
3
2
1
0
0
A
B
Z
START
Up
Down
Left
Right
1
L
R
C-up
C-Down
C-Left
C-Right
2
Joystick X value (signed, right positive)
3
Joystick Y value (signed, up positive)
GC Controller data
When the controller ID bytes order the extension ID indicates a Gamecube controller is connected,
the controller specific data is as follows:
Bit
Byte
7
6
5
4
3
2
1
0
0
START
Y
X
B
A
1
L
R
Z
Up
Down
Right
Left
2
Joystick X value (unsigned. Left low, Mid ~0x7F*, Right high)
3
Joystick Y value (unsigned. Down low, Mid ~0x7F*, Up high)
4
C-stick X value (unsigned. Down low, Mid ~0x7F*, Up high)
5
C-stick Y value (unsigned. Down low, Mid ~0x7F*, Up high)
6
Left shoulder value (unsigned. Released low, pressed high)
7
Right shoulder value (unsigned. Released low, pressed high)
SNES Controller data
When the controller ID bytes order the extension ID indicates an SNES controller is connected,
the controller specific data is as follows:
Bit
Byte
7
6
5
4
3
2
1
0
0
B
Y
SELECT
START
Up
Down
Left
Right
1
A
X
L
R
NES Controller data
When the controller ID bytes order the extension ID indicates a NES controller is connected,
the controller specific data is as follows:
The extra bytes are the analog N64 or GC values, exactly as received
from the controller. Bytes 12-14 are signature bytes used to detect
the extenmote adapter, but the two last bytes also serve to indicate
the type of controller (N64 or GC). This is important since N64 values
are signed while GC values are not, and also because the range
is different.
One thing to keep in mind is that the adapter can support more than
one type of controller. I.e, the application should continuously check
the signature bytes, not only once during init. Also note that due to
the dynamic controller handling, when first connected the adapter might
look like a normal classic controller, but one or two reads later the
signature bytes appear indicating a N64 or GC controller.
One last word about rumble: It is not supported yet, the current hardware
is inadequate. It is still documented in the hope that it will be
implemented and ready to test once I sort out the hardware.
/* | Bit |
* Byte | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
* ------+---------------+-------+----------------------------+
* 0 | RX<4:3> | LX<5:0> |
* 1 | RX<2:1> | LY<5:0> |
* 2 | RX<0> | LT<4:3> | RY<4:0> |
* 3 | LT<2:0> | RT<4:0> |
* 4 | BDR | BDD | BLT | B- | BH | B+ | BRT | 1 |
* 5 | BZL | BB | BY | BA | BX | BZR | BDL | BDU |
*
* 6 | GC Left stick/N64 stick raw X value |
* 7 | GC Left stick/N64 stick raw Y value |
* 8 | GC C-stick raw X value |
* 9 | GC C-stick raw Y value |
* 10 | GC Left shoulder raw X value |
* 11 | GC Right shoulder raw Y value |
* 12 | 0x52 ('R') |
* 13 | Controller ID byte 0 |
* 14 | Controller ID byte 1 |
* 15 | Rumble status (RW) for future use |
*
* Controller ID:
*
* 0 | 1
* -----+-----
* '6' | '4' N64 controller
* 'G' | 'C' Gamecube controller
*
* When neither a N64 nor GC controller is connected, all values from
* byte 6 up to byte 14 are 0x00.
*
* Writing at byte 15 controls the rumble motor. Rumbles on when non-zero.
*/
Old example (v1.8)
This structure was only used in version 1.8. Soon after, I decided to
add button data, making available the full raw data.